import 'dart:convert';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/controller/cache.dart';
import 'package:ichinesereader/models/book/BookFilters.dart';
import 'package:ichinesereader/models/book/BookFolders.dart';
import 'package:ichinesereader/models/book/BookItem.dart';
import 'package:ichinesereader/models/book/BookRelease.dart';
import 'package:ichinesereader/models/book/BookSearchDto.dart';
import 'package:ichinesereader/models/book/BooksDataSummaryResult.dart';
import 'package:ichinesereader/models/book/LeveledBookNumberResult.dart';
import 'package:ichinesereader/models/book/MostReadBook.dart';
import 'package:ichinesereader/models/book/MostReadBooksResult.dart';
import 'package:ichinesereader/models/book/MyLibraryBooks.dart';
import 'package:ichinesereader/models/book/NewBook.dart';
import 'package:ichinesereader/models/book/OpenReadingBooks.dart';
import 'package:ichinesereader/models/book/ProgramBookLists.dart';
import 'package:ichinesereader/models/book/ProgressReadingBooks.dart';
import 'package:ichinesereader/models/book/RecordLocation.dart';
import 'package:ichinesereader/models/book/audioPlaylistResult.dart';
import 'package:ichinesereader/models/book/bookAssigned.dart';
import 'package:ichinesereader/models/book/bookKnowledgeStatusResult.dart';
import 'package:ichinesereader/models/book/categoryForSeries.dart';
import 'package:ichinesereader/models/book/myFolderBooksResult.dart';
import 'package:ichinesereader/models/common/LevelOption.dart';
import 'package:ichinesereader/models/common/Settings.dart';
import 'package:ichinesereader/models/common/StatusMessageResult.dart';
import 'package:ichinesereader/models/report/bookReleaseChartData.dart';
import 'package:ichinesereader/models/report/bookchartdata.dart';
import 'package:ichinesereader/models/student/AssignmentDetail.dart';
import 'package:ichinesereader/models/student/Assignments.dart';
import 'package:ichinesereader/service/book.dart';
import 'package:ichinesereader/service/schooladmin.dart';
import 'package:ichinesereader/utils/StrUtil.dart';
import 'package:ichinesereader/utils/helper.dart';
import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:ichinesereader/utils/log.dart';

//import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:reactive_forms/reactive_forms.dart';

class BooksController extends GetxController with StateMixin<dynamic> {
  BookServiceProvider _bookServiceProvider = new BookServiceProvider();
  SchoolAdminServiceProvider _adminServiceProvider =
      new SchoolAdminServiceProvider();
  final box = Hive.box('appconfig');

  List<BookItem> _openLibraryReadingBookItems = <BookItem>[].obs;
  List<BookItem> _searchedBookItems = <BookItem>[].obs;
  List<BookItem> _leveledReadingBookItems = <BookItem>[].obs;
  List<BookItem> _myFavoriteBookItems = <BookItem>[].obs;
  List<BookItem> _newBookItems = <BookItem>[].obs;
  List<BookItem> _audioPlayBookItems = <BookItem>[].obs;
  List<BookItem> _themedBookItems = <BookItem>[].obs;
  List<BookItem> _selectedLeveledReadingBookItems = <BookItem>[].obs;
  List<BookItem> _selectedLibraryReadingBookItems = <BookItem>[].obs;
  List<BookItem> _selectedFavoriteReadingBookItems = <BookItem>[].obs;
  List<BookItem> _selectedSearchedReadingBookItems = <BookItem>[].obs;
  List<BookItem> _selectedAssignedBookItems = <BookItem>[].obs;
  List<BookItem> _selectedEvaluationBookItems = <BookItem>[].obs;
  List<ProgramBookList> _programBookList = <ProgramBookList>[].obs;
  List<BookItem> _selectedThemedBookItems = <BookItem>[].obs;
  List<BookItem> _selectedTextBookItems = <BookItem>[].obs;
  List<BookItem> _recommendedBookItems = <BookItem>[].obs;

  List<AllFolder> _bookFolders = <AllFolder>[].obs;
  Rx<AllFolder> _currentBookFolder = Rx<AllFolder>(AllFolder());
  Rx<AllFolder> _currentBookFolder2 = Rx<AllFolder>(AllFolder());
  List<BookItem> _mostReadBookItems = <BookItem>[].obs;
  List<BookItem> _mostReadBookItemsSchool = <BookItem>[].obs;

  Rx<StatusMessageResult> _statusMessageResult =
      Rx<StatusMessageResult>(StatusMessageResult());
  List<BookChartData> _bookleveldata = <BookChartData>[].obs;
  List<BookChartData> _booktopicsdata = <BookChartData>[].obs;
  List<BookFilter> _bookfilters = <BookFilter>[].obs;
  List<BookItem> _assignedBookItems = <BookItem>[].obs;
  List<CategoryForSeries> _bookCategorySeries = <CategoryForSeries>[].obs;

  List<CategoryForSeries> get bookCategorySeries => this._bookCategorySeries;
  StatusMessageResult _statusResult = new StatusMessageResult();
  List<LevelOption> _levelOptions = <LevelOption>[].obs;
  Rx<BooksDataSummaryResult> _booksDataSummary =
      Rx<BooksDataSummaryResult>(BooksDataSummaryResult());
  Rx<BookRelease> _bookRelease = Rx<BookRelease>(BookRelease());
  List<BookReleaseChartData> _bookReleaseData = <BookReleaseChartData>[].obs;
  Rx<bool> _showBookBarRecord = Rx<bool>(false.obs.value);
  Rx<bool> _showBookBarSetting = Rx<bool>(false.obs.value);
  RxString _myWriting = ''.obs;
  RxString _bookGrammer = ''.obs;
  RxString _myCurrentWriting = ''.obs;

  var _currentPage = 0;
  var _currentPageLimit;
  var _currentAssignmentSettings;

  //var _currentProfileSettings;
  var _folderId;
  var _classId;
  var _assignmentId;
  var _level = '1';
  var _progress = '0';
  late AssignmentDetail assignmentDetail;

  BookSearchDto dto = new BookSearchDto();

  List<BookItem> get assignedBookItems => this._assignedBookItems;

  List<BookItem> get openLibraryReadingBookItems =>
      this._openLibraryReadingBookItems;

  List<BookItem> get recommendedBookItems => this._recommendedBookItems;

  List<BookItem> get leveledReadingBookItems => this._leveledReadingBookItems;

  List<BookItem> get myFavoriteBookItems => this._myFavoriteBookItems;

  List<BookItem> get newBookItems => this._newBookItems;

  List<BookItem> get audioPlayBookItems => this._audioPlayBookItems;

  List<BookItem> get themedBookItems => this._themedBookItems;

  List<AllFolder> get bookFolders => this._bookFolders;

  Rx<AllFolder> get currentBookFolder => this._currentBookFolder;

  Rx<AllFolder> get currentBookFolder2 => this._currentBookFolder2;

  List<BookItem> get mostReadBookItems => this._mostReadBookItems;

  List<BookItem> get mostReadBookItemsSchool => this._mostReadBookItemsSchool;

  List<BookItem> get searchedBookItems => this._searchedBookItems;

  List<BookItem> get selectedThemedBookItems => this._selectedThemedBookItems;

  List<BookItem> get selectedEvaluationBookItems =>
      this._selectedEvaluationBookItems;

  List<BookItem> get selectedTextBookItems => this._selectedThemedBookItems;

  List<BookItem> _evaluationBookItems = <BookItem>[].obs;

  List<BookItem> get evaluationBookItems => this._evaluationBookItems;

  Rx<StatusMessageResult> get statusMessageResult => this._statusMessageResult;

  Rx<BooksDataSummaryResult> get booksDataSummary => this._booksDataSummary;

  List<BookChartData> get bookleveldata => this._bookleveldata;

  List<BookChartData> get booktopicsdata => this._booktopicsdata;

  List<BookFilter> get bookfilters => this._bookfilters;

  List<BookItem> get selectedLeveledReadingBookItems =>
      this._selectedLeveledReadingBookItems;

  List<BookItem> get selectedLibraryReadingBookItems =>
      this._selectedLibraryReadingBookItems;

  List<BookItem> get selectedFavoriteReadingBookItems =>
      this._selectedFavoriteReadingBookItems;

  List<BookItem> get selectedSearchedBookItems =>
      this._selectedSearchedReadingBookItems;

  List<BookItem> get selectedAssignedBookItems =>
      this._selectedAssignedBookItems;
  List<AllFolder> allBookFolders = [];

  List<ProgramBookList> get programBookList => this._programBookList;
  RxInt libraryBooksTotalNum = 0.obs;
  RxInt leveledBooksTotalNum = 0.obs;
  RxInt themedBooksTotalNum = 0.obs;
  RxInt defaultPage = 1.obs;
  RxString _currentBookId = ''.obs;

  RxString get currentBookId => this._currentBookId;
  BookItem _currentBook = BookItem();

  BookItem get getCurrentBook => this._currentBook;
  RxString _bookFullText = ''.obs;

  RxString get bookFullText => this._bookFullText;

  String get level => this._level;

  String get progress => this._progress;
  RxString _bookRecordingLocation = ''.obs;

  RxString get bookRecordingLocation => this._bookRecordingLocation;
  RxBool _isRecording = false.obs;

  RxBool get isRecording => this._isRecording;

  Rx<BookRelease> get bookRelease => this._bookRelease;

  List<LevelOption> get getLevelOptions => this._levelOptions;

  List<BookReleaseChartData> get bookReleaseData => this._bookReleaseData;

  Rx<bool> get showBookBarRecord => this._showBookBarRecord;

  Rx<bool> get showBookBarSetting => this._showBookBarSetting;

  RxString get myWriting => this._myWriting;

  RxString get myCurentWriting => this._myCurrentWriting;

  RxString get bookGrammer => this._bookGrammer;

  Rx<int> get getDefaultPage => this.defaultPage;

  // PagingController<int, BookItem> _pagingController =
  //     PagingController(firstPageKey: 0);
  // PagingController<int, BookItem> get getPagingController =>
  //     this._pagingController;

  @override
  void onInit() {
    super.onInit();
  }

  @override
  dispose() {
    super.dispose();
  }

  // disposePagingController() {
  //   _pagingController.dispose();
  // }

  // initPagingController() {
  //   _pagingController = PagingController(firstPageKey: 0);
  // }

  void setCurrentWriting(writing) {
    _myCurrentWriting.value = writing;
    change(this._myCurrentWriting, status: RxStatus.success());
  }

  void setShowBookBarRecord() {
    this._showBookBarSetting.value = false;
    if (this._showBookBarRecord.value) {
      this._showBookBarRecord.value = false;
    } else {
      this._showBookBarRecord.value = true;
    }
    change(_showBookBarRecord, status: RxStatus.success());
  }

  void closeToggles() {
    this._showBookBarSetting.value = false;
    this._showBookBarRecord.value = false;
    change(_showBookBarSetting, status: RxStatus.success());
    change(_showBookBarRecord, status: RxStatus.success());
  }

  void setShowBookBarClose() {
    this._showBookBarRecord.value = false;
    this._showBookBarSetting.value = false;
    this._myCurrentWriting = ''.obs;
    this._myWriting = ''.obs;
    change(_showBookBarSetting, status: RxStatus.success());
  }

  void setShowBookBarSetting() {
    this._showBookBarRecord.value = false;
    if (this._showBookBarSetting.value) {
      this._showBookBarSetting.value = false;
    } else {
      this._showBookBarSetting.value = true;
    }
    change(_showBookBarSetting, status: RxStatus.success());
  }

  void setCurrentBookId(String bookId) {
    this._currentBookId.value = bookId;
  }

  void setCurrentBook(BookItem book) {
    this._currentBook = book;
  }

  void selectedTextBookItemsClear() {
    this._selectedTextBookItems.clear();
  }

  void setSelectedTextBoookItems(List<BookItem> books) {
    this._selectedTextBookItems = books;
  }

  void selectedThemedBookItemsClear() {
    this._selectedThemedBookItems.clear();
    change(_selectedThemedBookItems, status: RxStatus.success());
  }

  void selectedFavoriteReadingBookItemsClear() {
    this._selectedFavoriteReadingBookItems.clear();
    change(_selectedFavoriteReadingBookItems, status: RxStatus.success());
  }

  void selectedLibraryReadingBookItemsClear() {
    this._selectedLibraryReadingBookItems.clear();
  }

  void selectedLevelReadingBookItemsClear() {
    this._selectedLeveledReadingBookItems.clear();
  }

  void refreshNewBookItems() {
    if (this._newBookItems.isNotEmpty) {
      change(_newBookItems, status: RxStatus.success());
    }
  }

  void refresBookLevelData() {
    if (this._bookleveldata.isNotEmpty) {
      change(_bookleveldata, status: RxStatus.success());
    }
    if (this._booktopicsdata.isNotEmpty) {
      change(_booktopicsdata, status: RxStatus.success());
    }
  }

  void resumeSelectedBookItemStatus(NanhaiBookReadingTypes readingType) {
    if (readingType == NanhaiBookReadingTypes.library) {
      this._selectedLibraryReadingBookItems.forEach((book) {
        var bk = this
            ._openLibraryReadingBookItems
            .where((element) => element.bookId == book.bookId)
            .first;
        if (bk.bookId != null) {
          bk.selected = false;
          change(_openLibraryReadingBookItems, status: RxStatus.success());
        }
      });
      this._selectedLibraryReadingBookItems.clear();
    }
    if (readingType == NanhaiBookReadingTypes.leveled) {
      this._selectedLeveledReadingBookItems.forEach((book) {
        var bk = this
            ._leveledReadingBookItems
            .where((element) => element.bookId == book.bookId)
            .first;
        if (bk.bookId != null) {
          bk.selected = false;
          change(_leveledReadingBookItems, status: RxStatus.success());
        }
      });
      this._selectedLeveledReadingBookItems.clear();
    }
    if (readingType == NanhaiBookReadingTypes.favorite) {
      this._selectedFavoriteReadingBookItems.forEach((book) {
        var bk = this
            ._myFavoriteBookItems
            .where((element) => element.bookId == book.bookId)
            .first;
        if (bk.bookId != null) {
          bk.selected = false;
          change(_myFavoriteBookItems, status: RxStatus.success());
        }
      });
      this._selectedFavoriteReadingBookItems.clear();
    }
    if (readingType == NanhaiBookReadingTypes.search) {
      this._selectedSearchedReadingBookItems.forEach((book) {
        var bk = this
            ._searchedBookItems
            .where((element) => element.bookId == book.bookId)
            .first;
        if (bk.bookId != null) {
          bk.selected = false;
          change(_searchedBookItems, status: RxStatus.success());
        }
      });
      this._selectedSearchedReadingBookItems.clear();
    }
    if (readingType == NanhaiBookReadingTypes.evaluation) {
      this._selectedEvaluationBookItems.forEach((book) {
        var bk = this
            ._selectedEvaluationBookItems
            .where((element) => element.bookId == book.bookId)
            .first;
        if (bk.bookId != null) {
          bk.selected = false;
          change(_evaluationBookItems, status: RxStatus.success());
        }
      });
      this._selectedEvaluationBookItems.clear();
    }

    if (readingType == NanhaiBookReadingTypes.theme) {
      this._selectedThemedBookItems.forEach((book) {
        var bk = this
            ._selectedThemedBookItems
            .where((element) => element.bookId == book.bookId)
            .first;
        if (bk.bookId != null) {
          bk.selected = false;
          change(_themedBookItems, status: RxStatus.success());
        }
      });
      this._selectedThemedBookItems.clear();
    }
  }

  void updateBookKnowledgeItemStatus(NanhaiBookReadingTypes readingType,
      NanhaiBookKnowledgeTypes knowledgeType, String bookId, String resultId) {
    if (knowledgeType == NanhaiBookKnowledgeTypes.wordcard) {
      if (readingType == NanhaiBookReadingTypes.library) {
        var bk = this
            ._openLibraryReadingBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.word = resultId;
          change(_openLibraryReadingBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.leveled) {
        var bk = this
            ._leveledReadingBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.word = resultId;
          change(_leveledReadingBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.favorite) {
        var bk = this
            ._myFavoriteBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.word = resultId;
          change(_myFavoriteBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.search) {
        var bk = this
            ._searchedBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.word = resultId;
          change(_searchedBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.assignment) {
        var bk = this
            ._assignedBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.word = resultId;
          change(_assignedBookItems, status: RxStatus.success());
        }
      }
    }
    if (knowledgeType == NanhaiBookKnowledgeTypes.quickReview) {
      if (readingType == NanhaiBookReadingTypes.library) {
        var bk = this
            ._openLibraryReadingBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.quickReview = resultId;
          change(_openLibraryReadingBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.leveled) {
        var bk = this
            ._leveledReadingBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.quickReview = resultId;
          change(_leveledReadingBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.favorite) {
        var bk = this
            ._myFavoriteBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.quickReview = resultId;
          change(_myFavoriteBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.search) {
        var bk = this
            ._searchedBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.quickReview = resultId;
          change(_searchedBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.assignment) {
        var bk = this
            ._assignedBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.quickReview = resultId;
          change(_assignedBookItems, status: RxStatus.success());
        }
      }
    }

    if (knowledgeType == NanhaiBookKnowledgeTypes.grammar) {
      if (readingType == NanhaiBookReadingTypes.library) {
        var bk = this
            ._openLibraryReadingBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.grammar = resultId;
          change(_openLibraryReadingBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.leveled) {
        var bk = this
            ._leveledReadingBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.grammar = resultId;
          change(_leveledReadingBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.favorite) {
        var bk = this
            ._myFavoriteBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.grammar = resultId;
          change(_myFavoriteBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.search) {
        var bk = this
            ._searchedBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.grammar = resultId;
          change(_searchedBookItems, status: RxStatus.success());
        }
      }
      if (readingType == NanhaiBookReadingTypes.assignment) {
        var bk = this
            ._assignedBookItems
            .where((element) => element.bookId == bookId)
            .first;
        if (bk.bookId != null) {
          bk.grammar = resultId;
          change(_assignedBookItems, status: RxStatus.success());
        }
      }
    }
  }

  // for update assignment books
  void addAssignedToSelectedBookItems(
      BookItem book, NanhaiBookReadingTypes readingType) {
    if (this
        ._selectedLibraryReadingBookItems
        .where((element) => element.bookId == book.bookId)
        .isEmpty) {
      this._selectedLibraryReadingBookItems.add(book);
    }
  }

  void removeAssignedFromSelectedBookItems(
      BookItem book, NanhaiBookReadingTypes readingType, FormGroup? form) {
    if (this
        ._selectedLibraryReadingBookItems
        .where((element) => element.bookId == book.bookId)
        .isNotEmpty) {
      this._selectedLibraryReadingBookItems.remove(book);
      form?.control('review.totalbooks').value =
          this.selectedLibraryReadingBookItems.length;
      form?.control('review.completerequired').value =
          this.selectedLibraryReadingBookItems.length;
      change(_openLibraryReadingBookItems, status: RxStatus.success());
      var bk = this
          ._openLibraryReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = false;
        change(_openLibraryReadingBookItems, status: RxStatus.success());
      }
    }
  }

  void addToSelectedBookItems(
      BookItem book, NanhaiBookReadingTypes readingType) {
    if (readingType == NanhaiBookReadingTypes.leveled) {
      if (this
          ._selectedLeveledReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isEmpty) {
        this._selectedLeveledReadingBookItems.add(book);
      }

      var bk = this
          ._leveledReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = true;
        change(_leveledReadingBookItems, status: RxStatus.success());
      }
    }
    if (readingType == NanhaiBookReadingTypes.library) {
      if (this
          ._selectedLibraryReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isEmpty) {
        this._selectedLibraryReadingBookItems.add(book);
      }

      var bk = this
          ._openLibraryReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = true;
        change(_openLibraryReadingBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.theme) {
      if (this
          ._selectedThemedBookItems
          .where((element) => element.bookId == book.bookId)
          .isEmpty) {
        this._selectedThemedBookItems.add(book);
      }
      var bk = this
          ._themedBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = true;
        change(_themedBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.favorite) {
      if (this
          ._selectedFavoriteReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isEmpty) {
        this._selectedFavoriteReadingBookItems.add(book);
      }
      var bk = this
          ._myFavoriteBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = true;
        change(_myFavoriteBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.search) {
      if (this
          ._selectedSearchedReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isEmpty) {
        this._selectedSearchedReadingBookItems.add(book);
      }
      var bk = this
          ._searchedBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = true;
        change(_searchedBookItems, status: RxStatus.success());
      }
      // for load more page search
      // var bk2 = this
      //     ._pagingController
      //     .itemList
      //     ?.where((element) => element.bookId == book.bookId)
      //     .first;
      // if (bk2?.bookId != null) {
      //   bk2?.selected = true;
      //   change(_pagingController.itemList, status: RxStatus.success());
      // }
    }
    if (readingType == NanhaiBookReadingTypes.assignment) {
      if (this
          ._selectedAssignedBookItems
          .where((element) => element.bookId == book.bookId)
          .isEmpty) {
        this._selectedAssignedBookItems.add(book);
      }
      var bk = this
          ._assignedBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = true;
        change(this._assignedBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.evaluation) {
      if (this
          ._selectedEvaluationBookItems
          .where((element) => element.bookId == book.bookId)
          .isEmpty) {
        this._selectedEvaluationBookItems.add(book);
      }
      var bk = this
          ._evaluationBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = true;
        change(this._evaluationBookItems, status: RxStatus.success());
      }
    }
  }

  void removeFromSelectedBookItems(
      BookItem book, NanhaiBookReadingTypes readingType) {
    if (readingType == NanhaiBookReadingTypes.leveled) {
      if (this
          ._selectedLeveledReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isNotEmpty) this._selectedLeveledReadingBookItems.remove(book);
      var bk = this
          ._leveledReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = false;
        change(_leveledReadingBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.library) {
      if (this
          ._selectedLibraryReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isNotEmpty) this._selectedLibraryReadingBookItems.remove(book);
      var bk = this
          ._openLibraryReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = false;
        change(_openLibraryReadingBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.favorite) {
      if (this
          ._selectedFavoriteReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isNotEmpty) this._selectedFavoriteReadingBookItems.remove(book);
      var bk = this
          ._myFavoriteBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = false;

        change(_myFavoriteBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.search) {
      if (this
          ._selectedSearchedReadingBookItems
          .where((element) => element.bookId == book.bookId)
          .isNotEmpty) this._selectedSearchedReadingBookItems.remove(book);
      var bk = this
          ._searchedBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = false;
        change(this._searchedBookItems, status: RxStatus.success());
      }
      // for load more page search
      // var bk2 = this
      //     ._pagingController
      //     .itemList
      //     ?.where((element) => element.bookId == book.bookId)
      //     .first;
      // if (bk2?.bookId != null) {
      //   bk2?.selected = false;
      //   change(_pagingController.itemList, status: RxStatus.success());
      // }
    }

    if (readingType == NanhaiBookReadingTypes.theme) {
      if (this
          ._selectedThemedBookItems
          .where((element) => element.bookId == book.bookId)
          .isNotEmpty) this._selectedThemedBookItems.remove(book);
      var bk = this
          ._themedBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = false;
        change(_themedBookItems, status: RxStatus.success());
      }
    }

    if (readingType == NanhaiBookReadingTypes.assignment) {
      if (this
          ._selectedAssignedBookItems
          .where((element) => element.bookId == book.bookId)
          .isNotEmpty) this._selectedAssignedBookItems.remove(book);
      var bk = this
          ._assignedBookItems
          .where((element) => element.bookId == book.bookId)
          .first;
      if (bk.bookId != null) {
        bk.selected = false;
        change(_assignedBookItems, status: RxStatus.success());
      }
    }
  }

  void setCurrentFileId(id) async {
    try {
      this._folderId = id;
    } catch (error) {
      Log.debug(error);
    }
  }

  void setCurrentClassId(id) async {
    try {
      this._classId = id;
    } catch (error) {
      Log.debug(error);
    }
  }

  void setCurrentAssignmentId(id) async {
    try {
      this._assignmentId = id;
    } catch (error) {
      Log.debug(error);
    }
  }

// have to update status mannually by call API because open book by webview
  void updateBookItemStatus(NanhaiBookReadingTypes? readingType) {
    final box = Hive.box('appconfig');
    bool isStudent = box.get(CacheManagerKey['nanhairole'].toString()) ==
        Constants.NanhaiRole_Student;
    bool isIndividual = box.get(CacheManagerKey['nanhairole'].toString()) ==
        Constants.NanhaiRole_Individual;
    if ((isStudent || isIndividual) &&
        readingType == NanhaiBookReadingTypes.library) {
      fetchOpenReadingItems(this._currentPageLimit, this._currentPage);
    }
    if ((isStudent || isIndividual) &&
        readingType == NanhaiBookReadingTypes.leveled) {
      fetchProgressReadingItems(this._currentPageLimit, this._currentPage);
    }
    if ((isStudent || isIndividual) &&
        readingType == NanhaiBookReadingTypes.favorite) {
      if (this._folderId != null)
        fetchMyFavoriteReadingItemsByFolder(this._folderId);
    }
    if (isStudent && readingType == NanhaiBookReadingTypes.assignment) {
      fetchAssignmentBookItemsById(this._classId, this._assignmentId);
    }
  }

  void clearOpenReadingBookItems() {
    if (_openLibraryReadingBookItems.isNotEmpty)
      _openLibraryReadingBookItems.clear();
  }

  void fetchProgramBookList(String programId) async {
    try {
      //change(_programBookList, status: RxStatus.loading());
      EasyLoading.show();
      var response = await _bookServiceProvider.getProgramBooklists(programId);
      if (response.statusCode == 200) {
        this._programBookList.clear();
        List<ProgramBookList> data =
            programBookListsFromJson(response.bodyString);
        _programBookList.assignAll(data);
        if (_programBookList.length > 0) {
          change(_programBookList, status: RxStatus.success());
        } else {
          change(_programBookList, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
        Log.debug('get program books error: ' '${response.body}');
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void checkBookKnowledgesStatus(
      List<String> bookCodes, NanhaiBookReadingTypes readingType) async {
    try {
      var response = await _bookServiceProvider.checkBookLightStatus(bookCodes);
      if (response.statusCode == 200) {
        var data = bookKnowledgeStatusResultFromJson(response.bodyString);
        if (readingType == NanhaiBookReadingTypes.library) {
          this._openLibraryReadingBookItems.forEach((bookItem) {
            var knowledgeStatus = data.result?[bookItem.bookCode];
            if (knowledgeStatus != null) {
              bookItem.grammar = knowledgeStatus.grammar;
              bookItem.word = knowledgeStatus.word;
              bookItem.quickReview = knowledgeStatus.quickReview;
            }
          });
          change(this._openLibraryReadingBookItems, status: RxStatus.success());
        }
        if (readingType == NanhaiBookReadingTypes.search) {
          this._searchedBookItems.forEach((bookItem) {
            var knowledgeStatus = data.result?[bookItem.bookCode];
            if (knowledgeStatus != null) {
              bookItem.grammar = knowledgeStatus.grammar;
              bookItem.word = knowledgeStatus.word;
              bookItem.quickReview = knowledgeStatus.quickReview;
            }
          });
          change(this._searchedBookItems, status: RxStatus.success());
          // for load more page
          // this._pagingController.itemList?.forEach((bookItem) {
          //   var knowledgeStatus = data.result?[bookItem.bookCode];
          //   if (knowledgeStatus != null) {
          //     bookItem.grammar = knowledgeStatus.grammar;
          //     bookItem.word = knowledgeStatus.word;
          //     bookItem.quickReview = knowledgeStatus.quickReview;
          //   }
          // });
          // change(this._pagingController.itemList, status: RxStatus.success());
        }
        if (readingType == NanhaiBookReadingTypes.favorite) {
          this._myFavoriteBookItems.forEach((bookItem) {
            var knowledgeStatus = data.result?[bookItem.bookCode];
            if (knowledgeStatus != null) {
              bookItem.grammar = knowledgeStatus.grammar;
              bookItem.word = knowledgeStatus.word;
              bookItem.quickReview = knowledgeStatus.quickReview;
            }
          });
          change(this._myFavoriteBookItems, status: RxStatus.success());
        }
        if (readingType == NanhaiBookReadingTypes.leveled) {
          this._leveledReadingBookItems.forEach((bookItem) {
            var knowledgeStatus = data.result?[bookItem.bookCode];
            if (knowledgeStatus != null) {
              bookItem.grammar = knowledgeStatus.grammar;
              bookItem.word = knowledgeStatus.word;
              bookItem.quickReview = knowledgeStatus.quickReview;
            }
          });
          change(this._leveledReadingBookItems, status: RxStatus.success());
        }
        if (readingType == NanhaiBookReadingTypes.assignment) {
          this._assignedBookItems.forEach((bookItem) {
            var knowledgeStatus = data.result?[bookItem.bookCode];
            if (knowledgeStatus != null) {
              bookItem.grammar = knowledgeStatus.grammar;
              bookItem.word = knowledgeStatus.word;
              bookItem.quickReview = knowledgeStatus.quickReview;
            }
          });
          change(this._assignedBookItems, status: RxStatus.success());
        }
      }
    } catch (e) {
      Log.debug(e);
    }
  }

  void checkBookAssignmentStatus(String classId, List<String> bookIds,
      NanhaiBookReadingTypes readingType) async {
    try {
      var response =
          await _bookServiceProvider.checkIfBookAssigned(classId, bookIds);
      if (response.statusCode == 200) {
        var data = bookAssignedFromJson(response.bodyString);
        if (readingType == NanhaiBookReadingTypes.library) {
          this._openLibraryReadingBookItems.forEach((bookItem) {
            var index =
                data.indexWhere((element) => element.bookId == bookItem.bookId);
            if (index != -1) {
              bookItem.ifAssigned = data[index].ifAssigned ?? false;
            }
          });
          change(this._openLibraryReadingBookItems, status: RxStatus.success());
        }
        if (readingType == NanhaiBookReadingTypes.search) {
          this._searchedBookItems.forEach((bookItem) {
            var index =
                data.indexWhere((element) => element.bookId == bookItem.bookId);
            if (index != -1) {
              bookItem.ifAssigned = data[index].ifAssigned ?? false;
            }
          });
          change(this._searchedBookItems, status: RxStatus.success());
        }

        if (readingType == NanhaiBookReadingTypes.theme) {
          this._themedBookItems.forEach((bookItem) {
            var index =
                data.indexWhere((element) => element.bookId == bookItem.bookId);
            if (index != -1) {
              bookItem.ifAssigned = data[index].ifAssigned ?? false;
            }
          });
          change(this._themedBookItems, status: RxStatus.success());
        }

        if (readingType == NanhaiBookReadingTypes.favorite) {
          this._myFavoriteBookItems.forEach((bookItem) {
            var index =
                data.indexWhere((element) => element.bookId == bookItem.bookId);
            if (index != -1) {
              bookItem.ifAssigned = data[index].ifAssigned ?? false;
            }
          });
          change(this._myFavoriteBookItems, status: RxStatus.success());
        }
      }
    } catch (e) {}
  }

  void setOpenReadingItems(OpenReadingBooksResult data, bool initial) {
    List<String> bookCodes = [];
    List<String> bookIds = [];
    List<BookItem> items = [];
    var _language = box.get('UserLanguage') ?? 'Simplified';
    for (int i = 0; i < data.list!.length; i++) {
      BookItem item = BookItem();
      item.bookCode = data.list![i].book?.bookCode ?? '';
      item.audio = data.list![i].book?.audio ?? '';
      item.bookId = data.list![i].book?.bookId ?? '';
      item.bilingual = data.list![i].book?.bilingual ?? false;
      item.bookContentLink = data.list![i].book?.bookContentLink ?? '';
      item.simBookImageLink = data.list![i].book?.bookImageLink ?? '';
      item.viewMode = data.list![i].book?.viewMode;
      if (_language == 'Traditional') {
        item.bookTitle = data.list![i].book?.traditionalTitle ?? '';
        item.bookImageLink = StrUtil.insertCharAt(
                item.simBookImageLink!, item.simBookImageLink!.length - 4, "t")
            .replaceAll('.gif', '.jpg');
      } else {
        item.bookTitle = data.list![i].book?.bookTitle ?? '';
        item.bookImageLink = item.simBookImageLink;
      }
      item.description = data.list![i].book?.description ?? item.bookTitle;
      item.newArival = data.list![i].book?.newArival ?? false;
      item.topBook = data.list![i].book?.topBook ?? false;
      item.lastReadAt = data.list![i].lastReadAt ?? 0;
      item.quiz = data.list![i].book?.quiz ?? false;
      item.quizAvailable = data.list![i].quizAvailable ?? false;
      item.quizCount = data.list![i].quizCount ?? 0;
      item.quizLinkUrl = data.list![i].book?.quizLinkUrl ?? '';
      //api5
      item.color = data.list![i].book?.color ?? '#808080';
      item.bookLevel = data.list![i].book?.bookLevel ?? '';
      ////apiv4
      // item.color = data.list![i].book?.level?.color ?? '#808080';
      // item.bookLevel = data.list![i].book?.level?.levelCode ?? '';
      item.readComplete = data.list![i].readComplete ?? false;
      item.readCount = data.list![i].readCount ?? 0;
      item.readProgress = data.list![i].readProgress ?? 0;
      item.pass = data.list![i].pass ?? false;
      item.inFolder = data.list![i].inFolder ?? false;
      item.inAudioPlaylist = data.list![i].inAudioPlaylist ?? false;
      item.traditionalTitle = data.list![i].book?.traditionalTitle ?? '';
      if (items.where((element) => element.bookId == item.bookId).length == 0) {
        items.add(item);
        bookCodes.add(item.bookCode.toString());
        bookIds.add(item.bookId.toString());
      }
      Log.debug(item.readProgress);
      if (this
          ._selectedLibraryReadingBookItems
          .where((element) => element.bookId == item.bookId)
          .isNotEmpty) {
        item.selected = true;
      }
    }
    if (initial) {
      _openLibraryReadingBookItems.assignAll(items);
    } else {
      _openLibraryReadingBookItems.addAll(items);
    }

    if (_openLibraryReadingBookItems.length > 0) {
      change(_openLibraryReadingBookItems, status: RxStatus.success());
      bool isTeacher = box.get(CacheManagerKey['nanhairole'].toString()) ==
          Constants.NanhaiRole_Teacher;
      if (isTeacher) {
        var _classId = box.get(CacheManagerKey['currentclass'].toString());
        checkBookAssignmentStatus(
            _classId, bookIds, NanhaiBookReadingTypes.library);
      } else {
        bool isStudentOrIndividual =
            box.get(CacheManagerKey['nanhairole'].toString()) ==
                    Constants.NanhaiRole_Student ||
                box.get(CacheManagerKey['nanhairole'].toString()) ==
                    Constants.NanhaiRole_Individual;
        if (isStudentOrIndividual) {
          checkBookKnowledgesStatus(bookCodes, NanhaiBookReadingTypes.library);
        }
      }
    } else {
      change(_openLibraryReadingBookItems, status: RxStatus.empty());
    }
  }

  // fetch the first page and initialize the load more data
  void fetchOpenReadingItems(int limit, int page) async {
    setCurrentPage(page);
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider.searchOpenReadingBooks(
          limit, page, this.dto, '');
      if (response.statusCode == 200) {
        OpenReadingBooksResult data =
            OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
        libraryBooksTotalNum.value = data.count!;
        setOpenReadingItems(data, true);
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  // load more indead of pagination
  void fetchMoreOpenReadingItems() async {
    try {
      // if (this._openLibraryReadingBookItems.isEmpty ||
      //     this._openLibraryReadingBookItems.length < 20) {
      //   return;
      // }
      EasyLoading.show();
      if (Constants.pageLimit * (this._currentPage + 1) <
          libraryBooksTotalNum.value) {
        var response = await _bookServiceProvider.searchOpenReadingBooks(
            Constants.pageLimit, this._currentPage + 1, this.dto, '');
        if (response.statusCode == 200) {
          OpenReadingBooksResult data =
              OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
          setOpenReadingItems(data, false);
          //if (items.length == Constants.pageLimit) {
          this._currentPage = this._currentPage + 1;
          //}
        }
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  Future<void> setCurrentAssignmentSettings(Settings assignmentSettings) async {
    try {
      this._currentAssignmentSettings = assignmentSettings;
    } catch (error) {
      Log.debug(error);
    }
  }

  Settings? getCurrentAssignmentSettings() {
    try {
      return this._currentAssignmentSettings;
    } catch (error) {
      Log.debug(error);
      return null;
    }
  }

  String settingsToJson(Settings? data) => json.encode(data!.toJson());

  void fetchAssignmentBookItemsById(String classId, String assignmentId) async {
    final box = Hive.box('appconfig');
    try {
      EasyLoading.show();
      List<String> bookCodes = [];
      var response = await _adminServiceProvider
          .getAssignmentDetailsByAssignmentId(classId, assignmentId);
      // test HomeworkDetailedBooks for sdudent
      // var response = await _adminServiceProvider
      //     .getAssignmentDetailsByAssignmentIdNew(classId, assignmentId);
      if (response.statusCode == 200) {
        var data = assignmentFromJson(response.bodyString);
        List<BookItem> items = [];
        // use for instruction
        assignmentDetail = data.assignment!;
        Settings? _assignmentSettings = data.assignment!.settings;

        setCurrentAssignmentSettings(_assignmentSettings!);
        var language = data.assignment!.settings!.language;
        // assigment seeting has the most priority
        if (data.assignment!.settings != null) {
          box.put(
              'assignmentSettings', settingsToJson(data.assignment!.settings));
        }
        box.put('UserAssiLang', data.assignment!.settings!.lang ?? 'Mandarin');
        box.put('UserAssiLanguage', language ?? 'Simplified');
        for (int i = 0; i < data.bookProgress!.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data.bookProgress![i].book?.bookCode ?? '';
          item.audio = data.bookProgress![i].book?.audio ?? '';
          item.bookId = data.bookProgress![i].book?.bookId ?? '';
          item.bilingual = data.bookProgress![i].book?.bilingual ?? false;
          item.bookContentLink =
              data.bookProgress![i].book?.bookContentLink ?? '';
          item.simBookImageLink =
              data.bookProgress![i].book?.bookImageLink ?? '';
          if (language == 'Traditional') {
            item.bookTitle = data.bookProgress![i].book?.traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
          } else {
            item.bookTitle = data.bookProgress![i].book?.bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          item.description =
              data.bookProgress![i].book?.description ?? item.bookTitle;
          item.newArival = data.bookProgress![i].book?.newArival ?? false;
          item.topBook = data.bookProgress![i].book?.topBook ?? false;
          item.lastReadAt = data.bookProgress![i].lastReadAt ?? 0;
          item.quiz = data.bookProgress![i].book?.quiz ?? false;
          item.quizAvailable = data.bookProgress![i].quizAvailable ?? false;
          item.quizCount = data.bookProgress![i].quizCount ?? 0;
          item.quizLinkUrl = data.bookProgress![i].book?.quizLinkUrl ?? '';
          item.viewMode = data.bookProgress![i].book?.viewMode;
          //api5
          item.color = data.bookProgress![i].book?.color ?? '#808080';
          item.bookLevel = data.bookProgress![i].book?.bookLevel ?? '';
          item.readComplete = data.bookProgress![i].readComplete ?? false;
          item.readCount = data.bookProgress![i].readCount ?? 0;
          item.readProgress = data.bookProgress![i].readProgress ?? 0;
          //item.pass = data.bookProgress![i].pass ?? false;
          item.pass = data.bookProgress![i].maxScore?.pass ?? false;
          item.inFolder = data.bookProgress![i].inFolder ?? false;
          item.inAudioPlaylist = data.bookProgress![i].inAudioPlaylist ?? false;
          // item.traditionalTitle =
          //     data.bookProgress![i].book?.traditionalTitle ?? '';
          if (items.where((element) => element.bookId == item.bookId).length ==
              0) {
            items.add(item);
            bookCodes.add(item.bookCode.toString());
          }
        }
        _assignedBookItems.assignAll(items);
        if (_assignedBookItems.length > 0) {
          change(_assignedBookItems, status: RxStatus.success());
          checkBookKnowledgesStatus(
              bookCodes, NanhaiBookReadingTypes.assignment);
          Log.debug(_assignedBookItems.length);
        } else {
          change(_assignedBookItems, status: RxStatus.empty());
        }
      } else {
        change(_assignedBookItems, status: RxStatus.empty());
        //change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
        Log.debug('error when geting assigned books by assignment id');
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  Future<List<BookItem>> fetchSearchedBookItemsRes(int limit, int page,
      BookSearchDto bookSearchDto, String sortField) async {
    try {
      //EasyLoading.show();
      List<String> bookCodes = [];
      List<String> bookIds = [];
      var response = await _bookServiceProvider.searchOpenReadingBooks(
          limit, page, bookSearchDto, sortField);
      if (response.statusCode == 200) {
        OpenReadingBooksResult data =
            OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
        var _language = box.get('UserLanguage') ?? 'Simplified';
        List<BookItem> items = [];
        for (int i = 0; i < data.list!.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data.list![i].book?.bookCode ?? '';
          item.audio = data.list![i].book?.audio ?? '';
          item.bookId = data.list![i].book?.bookId ?? '';
          item.bilingual = data.list![i].book?.bilingual ?? false;
          item.bookContentLink = data.list![i].book?.bookContentLink ?? '';
          item.simBookImageLink = data.list![i].book?.bookImageLink ?? '';
          if (_language == 'Traditional') {
            item.bookTitle = data.list![i].book?.traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
            // Log.debug(insertCharAt(item.simBookImageLink!,
            //     item.simBookImageLink!.length - 4, "t"));
          } else {
            item.bookTitle = data.list![i].book?.bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          // item.bookImageLink = data.list![i].book?.bookImageLink ?? '';
          // item.bookTitle = data.list![i].book?.bookTitle ?? '';
          item.description = data.list![i].book?.description ?? item.bookTitle;
          item.newArival = data.list![i].book?.newArival ?? false;
          item.topBook = data.list![i].book?.topBook ?? false;
          item.lastReadAt = data.list![i].lastReadAt ?? 0;
          item.quiz = data.list![i].book?.quiz ?? false;
          item.quizAvailable = data.list![i].quizAvailable ?? false;
          item.quizCount = data.list![i].quizCount ?? 0;
          item.quizLinkUrl = data.list![i].book?.quizLinkUrl ?? '';
          //api5
          item.color = data.list![i].book?.color ?? '#808080';
          item.bookLevel = data.list![i].book?.bookLevel ?? '';
          // item.color = data.list![i].book?.level?.color ?? '#808080';
          // item.bookLevel = data.list![i].book?.level?.levelCode ?? '';
          item.readComplete = data.list![i].readComplete ?? false;
          item.readCount = data.list![i].readCount ?? 0;
          item.readProgress = data.list![i].readProgress ?? 0;
          item.pass = data.list![i].pass ?? false;
          item.inFolder = data.list![i].inFolder ?? false;
          item.inAudioPlaylist = data.list![i].inAudioPlaylist ?? false;
          item.traditionalTitle = data.list![i].book?.traditionalTitle ?? '';
          item.viewMode = data.list![i].book?.viewMode;

          if (items.where((element) => element.bookId == item.bookId).length ==
              0) {
            items.add(item);
            bookCodes.add(item.bookCode.toString());
            bookIds.add(item.bookId.toString());
          }
        }
        _searchedBookItems.assignAll(items);

        if (_searchedBookItems.length > 0) {
          change(_searchedBookItems, status: RxStatus.success());
          bool isTeacher = box.get(CacheManagerKey['nanhairole'].toString()) ==
              Constants.NanhaiRole_Teacher;
          if (isTeacher) {
            var _classId = box.get(CacheManagerKey['currentclass'].toString());
            checkBookAssignmentStatus(
                _classId, bookIds, NanhaiBookReadingTypes.search);
          } else {
            bool isStudentOrIndividual =
                box.get(CacheManagerKey['nanhairole'].toString()) ==
                        Constants.NanhaiRole_Student ||
                    box.get(CacheManagerKey['nanhairole'].toString()) ==
                        Constants.NanhaiRole_Individual;
            if (isStudentOrIndividual) {
              checkBookKnowledgesStatus(
                  bookCodes, NanhaiBookReadingTypes.search);
            }
          }
        } else {
          change(null, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
        // Log.debug(response.body);
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      //EasyLoading.dismiss();
    }
    return _searchedBookItems;
  }

  void setSearchedBookItemsData(data, init) {
    List<String> bookCodes = [];
    List<String> bookIds = [];
    var _language = box.get('UserLanguage') ?? 'Simplified';
    List<BookItem> items = [];
    for (int i = 0; i < data.list!.length; i++) {
      BookItem item = BookItem();
      item.bookCode = data.list![i].book?.bookCode ?? '';
      item.audio = data.list![i].book?.audio ?? '';
      item.bookId = data.list![i].book?.bookId ?? '';
      item.bilingual = data.list![i].book?.bilingual ?? false;
      item.bookContentLink = data.list![i].book?.bookContentLink ?? '';
      item.simBookImageLink = data.list![i].book?.bookImageLink ?? '';
      if (_language == 'Traditional') {
        item.bookTitle = data.list![i].book?.traditionalTitle ?? '';
        item.bookImageLink = StrUtil.insertCharAt(
                item.simBookImageLink!, item.simBookImageLink!.length - 4, "t")
            .replaceAll('.gif', '.jpg');
      } else {
        item.bookTitle = data.list![i].book?.bookTitle ?? '';
        item.bookImageLink = item.simBookImageLink;
      }
      item.description = data.list![i].book?.description ?? item.bookTitle;
      item.newArival = data.list![i].book?.newArival ?? false;
      item.topBook = data.list![i].book?.topBook ?? false;
      item.lastReadAt = data.list![i].lastReadAt ?? 0;
      item.quiz = data.list![i].book?.quiz ?? false;
      item.quizAvailable = data.list![i].quizAvailable ?? false;
      item.quizCount = data.list![i].quizCount ?? 0;
      item.quizLinkUrl = data.list![i].book?.quizLinkUrl ?? '';
      //api5
      item.color = data.list![i].book?.color ?? '#808080';
      item.bookLevel = data.list![i].book?.bookLevel ?? '';
      item.readComplete = data.list![i].readComplete ?? false;
      item.readCount = data.list![i].readCount ?? 0;
      item.readProgress = data.list![i].readProgress ?? 0;
      item.pass = data.list![i].pass ?? false;
      item.inFolder = data.list![i].inFolder ?? false;
      item.inAudioPlaylist = data.list![i].inAudioPlaylist ?? false;
      item.traditionalTitle = data.list![i].book?.traditionalTitle ?? '';
      item.viewMode = data.list![i].book?.viewMode;

      if (items.where((element) => element.bookId == item.bookId).length == 0) {
        items.add(item);
        bookCodes.add(item.bookCode.toString());
        bookIds.add(item.bookId.toString());
      }
    }
    if (init) {
      _searchedBookItems.assignAll(items);
    } else {
      _searchedBookItems.addAll(items);
    }

    if (_searchedBookItems.length > 0) {
      change(_searchedBookItems, status: RxStatus.success());
      bool isTeacher = box.get(CacheManagerKey['nanhairole'].toString()) ==
          Constants.NanhaiRole_Teacher;
      if (isTeacher) {
        var _classId = box.get(CacheManagerKey['currentclass'].toString());
        checkBookAssignmentStatus(
            _classId, bookIds, NanhaiBookReadingTypes.search);
      } else {
        bool isStudentOrIndividual =
            box.get(CacheManagerKey['nanhairole'].toString()) ==
                    Constants.NanhaiRole_Student ||
                box.get(CacheManagerKey['nanhairole'].toString()) ==
                    Constants.NanhaiRole_Individual;
        if (isStudentOrIndividual) {
          checkBookKnowledgesStatus(bookCodes, NanhaiBookReadingTypes.search);
        }
      }
    } else {
      change(null, status: RxStatus.empty());
    }
  }

  // used by student homepage searching by leval and topics
  void fetchSearchedBookItems(int limit, int page, BookSearchDto bookSearchDto,
      String sortField) async {
    setCurrentPage(page);
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider.searchOpenReadingBooks(
          limit, page, bookSearchDto, sortField);
      if (response.statusCode == 200) {
        OpenReadingBooksResult data =
            OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
        libraryBooksTotalNum.value = data.count!;
        setSearchedBookItemsData(data, true);
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  // used by student homepage searching by leval and topics
  void fetchMoreSearchedBookItems() async {
    try {
      EasyLoading.show();
      if (Constants.pageLimit * (this._currentPage + 1) <
          libraryBooksTotalNum.value) {
        var response = await _bookServiceProvider.searchOpenReadingBooks(
            Constants.pageLimit, this._currentPage + 1, this.dto, 'level');
        if (response.statusCode == 200) {
          OpenReadingBooksResult data =
              OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
          setSearchedBookItemsData(data, false);
          this._currentPage = this._currentPage + 1;
        }
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void fetchSearchOpenLibraryBookItems(
      int limit, int page, BookSearchDto bookSearchDto) async {
    // initial current page when level changes
    setCurrentPage(page);
    try {
      this._selectedSearchedReadingBookItems.clear();
      EasyLoading.show();
      var response = await _bookServiceProvider.searchOpenReadingBooks(
          limit, page, bookSearchDto, '');
      if (response.statusCode == 200) {
        OpenReadingBooksResult data =
            OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
        libraryBooksTotalNum.value = data.count!;
        setOpenReadingItems(data, true);
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void setSearchProgressreadingBookItems(
      int limit, int page, BookSearchDto bookSearchDto) async {
    final box = Hive.box('appconfig');
    try {
      //this._selectedLeveledReadingBookItems.clear();
      //change(_leveledReadingBookItems, status: RxStatus.loading());
      List<String> bookCodes = [];
      var response = await _bookServiceProvider.searchProgressreadingBooks(
          limit, page, bookSearchDto);
      if (response.statusCode == 200) {
        var data = progressReadingBooksFromJson(response.bodyString);
        libraryBooksTotalNum.value = data.length;
        change(libraryBooksTotalNum, status: RxStatus.success());
        var _language = box.get('UserLanguage') ?? 'Simplified';
        List<BookItem> items = [];
        for (int i = 0; i < data.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data[i].book?.bookCode ?? '';
          item.audio = data[i].book?.audio ?? '';
          item.bookId = data[i].book?.bookId ?? '';
          item.bilingual = data[i].book?.bilingual ?? false;
          item.bookContentLink = data[i].book?.bookContentLink ?? '';
          item.simBookImageLink = data[i].book?.bookImageLink ?? '';
          if (_language == 'Traditional') {
            item.bookTitle = data[i].book?.traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
            // Log.debug(insertCharAt(item.simBookImageLink!,
            //     item.simBookImageLink!.length - 4, "t"));
          } else {
            item.bookTitle = data[i].book?.bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          item.description = data[i].book?.description ?? item.bookTitle;
          item.newArival = data[i].book?.newArival ?? false;
          item.topBook = data[i].book?.topBook ?? false;
          item.lastReadAt = data[i].lastReadAt ?? 0;
          item.quiz = data[i].book?.quiz ?? false;
          item.quizAvailable = data[i].quizAvailable ?? false;
          item.quizCount = data[i].quizCount ?? 0;
          item.quizLinkUrl = data[i].book?.quizLinkUrl ?? '';
          //api5
          item.color = data[i].book?.color ?? '#808080';
          item.bookLevel = data[i].book?.bookLevel ?? '';
          // item.color = data[i].book?.level?.color ?? '#808080';
          // item.bookLevel = data[i].book?.level?.levelCode ?? '';
          item.readComplete = data[i].readComplete ?? false;
          item.readCount = data[i].readCount ?? 0;
          item.readProgress = data[i].readProgress ?? 0;
          item.pass = data[i].pass ?? false;
          item.inFolder = data[i].inFolder ?? false;
          item.inAudioPlaylist = data[i].inAudioPlaylist ?? false;
          item.traditionalTitle = data[i].book?.traditionalTitle ?? '';
          item.viewMode = data[i].book?.viewMode;

          if (items.where((element) => element.bookId == item.bookId).length ==
              0) {
            items.add(item);
            bookCodes.add(item.bookCode.toString());
          }
        }
        _leveledReadingBookItems.assignAll(items);

        if (_leveledReadingBookItems.length > 0) {
          change(_leveledReadingBookItems, status: RxStatus.success());
          checkBookKnowledgesStatus(bookCodes, NanhaiBookReadingTypes.leveled);
          //Log.debug(openReadingBookItems.length);
        } else {
          change(null, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
        // Log.debug(response.body);
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    }
  }

  void fetchSearchProgressreadingBookItems(
      int limit, int page, BookSearchDto bookSearchDto) async {
    setCurrentPageLimit(limit);
    setCurrentPage(page);
    // call clount page API in first page
    if (page == 0) {
      try {
        var response = await _bookServiceProvider
            .getProgressReadingBooksTotalNumber(this.dto);
        if (response.statusCode == 200) {
          var data = LeveledBookNumberResult.fromJson(
              json.decode(response.bodyString));
          //Log.debug('controller----${data.count!.toInt()}');
          leveledBooksTotalNum.value =
              data.count != null ? data.count!.toInt() : 0;
          setSearchProgressreadingBookItems(limit, page, bookSearchDto);
        }
      } catch (error) {
        Log.debug(error);
      }
    } else {
      setProgressReadingItems(limit, page);
    }
  }

  void setProgramThemeBookItems(data, init) async {
    List<String> bookIds = [];
    var _language = box.get('UserLanguage') ?? 'Simplified';
    List<BookItem> items = [];
    for (int i = 0; i < data.list!.length; i++) {
      BookItem item = BookItem();
      item.bookCode = data.list![i].book?.bookCode ?? '';
      item.audio = data.list![i].book?.audio ?? '';
      item.bookId = data.list![i].book?.bookId ?? '';
      item.bilingual = data.list![i].book?.bilingual ?? false;
      item.description = data.list![i].book?.description ?? item.bookTitle;
      item.bookContentLink = data.list![i].book?.bookContentLink ?? '';
      item.simBookImageLink = data.list![i].book?.bookImageLink ?? '';
      if (_language == 'Traditional') {
        item.bookTitle = data.list![i].book?.traditionalTitle ?? '';
        item.bookImageLink = StrUtil.insertCharAt(
                item.simBookImageLink!, item.simBookImageLink!.length - 4, "t")
            .replaceAll('.gif', '.jpg');
      } else {
        item.bookTitle = data.list![i].book?.bookTitle ?? '';
        item.bookImageLink = item.simBookImageLink;
      }
      item.newArival = data.list![i].book?.newArival ?? false;
      item.topBook = data.list![i].book?.topBook ?? false;
      item.lastReadAt = data.list![i].lastReadAt ?? 0;
      item.quiz = data.list![i].book?.quiz ?? false;
      item.quizAvailable = data.list![i].quizAvailable ?? false;
      item.quizCount = data.list![i].quizCount ?? 0;
      item.quizLinkUrl = data.list![i].book?.quizLinkUrl ?? '';
      //api5
      item.color = data.list![i].book?.color ?? '#808080';
      item.bookLevel = data.list![i].book?.bookLevel ?? '';
      // item.color = data.list![i].book?.level?.color ?? '#808080';
      // item.bookLevel = data.list![i].book?.level?.levelCode ?? '';
      item.readComplete = data.list![i].readComplete ?? false;
      item.readCount = data.list![i].readCount ?? 0;
      item.readProgress = data.list![i].readProgress ?? 0;
      item.pass = data.list![i].pass ?? false;
      item.inFolder = data.list![i].inFolder ?? false;
      item.inAudioPlaylist = data.list![i].inAudioPlaylist ?? false;
      item.traditionalTitle = data.list![i].book?.traditionalTitle ?? '';
      item.viewMode = data.list![i].book?.viewMode;

      if (items.where((element) => element.bookId == item.bookId).length == 0) {
        items.add(item);
        bookIds.add(item.bookId.toString());
      }

      if (this
          ._selectedThemedBookItems
          .where((element) => element.bookId == item.bookId)
          .isNotEmpty) {
        item.selected = true;
      }
    }

    if (items.isNotEmpty) {
      if (init) {
        _themedBookItems.assignAll(items);
      } else {
        _themedBookItems.addAll(items);
      }
      change(_themedBookItems, status: RxStatus.success());
      bool isTeacher = box.get(CacheManagerKey['nanhairole'].toString()) ==
          Constants.NanhaiRole_Teacher;
      if (isTeacher) {
        var _classId = box.get(CacheManagerKey['currentclass'].toString());
        checkBookAssignmentStatus(
            _classId, bookIds, NanhaiBookReadingTypes.theme);
      }
    } else {
      change(null, status: RxStatus.empty());
    }
  }

  void fetchProgramThemeBookItems(
      int limit, int page, BookSearchDto bookSearchDto) async {
    setCurrentPage(page);
    try {
      EasyLoading.show();
      this.dto = bookSearchDto;
      var response = await _bookServiceProvider.searchOpenReadingBooks(
          limit, page, bookSearchDto, 'level');
      if (response.statusCode == 200) {
        OpenReadingBooksResult data =
            OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
        themedBooksTotalNum.value = data.count!.toInt();
        setProgramThemeBookItems(data, true);
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void fetchMoreProgramThemeBookItems() async {
    try {
      EasyLoading.show();
      if (Constants.pageLimit * (this._currentPage + 1) <
          themedBooksTotalNum.value) {
        var response = await _bookServiceProvider.searchOpenReadingBooks(
            Constants.pageLimit, this._currentPage + 1, this.dto, 'level');
        if (response.statusCode == 200) {
          OpenReadingBooksResult data =
              OpenReadingBooksResult.fromJson(json.decode(response.bodyString));
          setProgramThemeBookItems(data, false);
          this._currentPage = this._currentPage + 1;
        } else {
          change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
        }
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void getLeveledBooksTotalNumber() async {
    try {
      var response = await _bookServiceProvider
          .getProgressReadingBooksTotalNumber(this.dto);
      if (response.statusCode == 200) {
        var data =
            LeveledBookNumberResult.fromJson(json.decode(response.bodyString));
        leveledBooksTotalNum.value =
            data.count != null ? data.count!.toInt() : 0;
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  void setProgressReadingDataItems(data, init) {
    List<String> bookCodes = [];
    List<BookItem> items = [];
    var _language = box.get('UserLanguage') ?? 'Simplified';
    for (int i = 0; i < data.length; i++) {
      BookItem item = BookItem();
      item.bookCode = data[i].book?.bookCode ?? '';
      item.audio = data[i].book?.audio ?? '';
      item.bookId = data[i].book?.bookId ?? '';
      item.bilingual = data[i].book?.bilingual ?? false;
      item.bookContentLink = data[i].book?.bookContentLink ?? '';
      // item.bookImageLink = data[i].book?.bookImageLink ?? '';
      // item.bookTitle = data[i].book?.bookTitle ?? '';
      item.simBookImageLink = data[i].book?.bookImageLink ?? '';
      // final box = Hive.box('appconfig');
      // var _language = box.get('UserLanguage') ?? 'Simplified';
      if (_language == 'Traditional') {
        item.bookTitle = data[i].book?.traditionalTitle ?? '';
        item.bookImageLink = StrUtil.insertCharAt(
                item.simBookImageLink!, item.simBookImageLink!.length - 4, "t")
            .replaceAll('.gif', '.jpg');
        // Log.debug(insertCharAt(item.simBookImageLink!,
        //     item.simBookImageLink!.length - 4, "t"));
      } else {
        item.bookTitle = data[i].book?.bookTitle ?? '';
        item.bookImageLink = item.simBookImageLink;
      }
      item.description = data[i].book?.description ?? item.bookTitle;
      item.newArival = data[i].book?.newArival ?? false;
      item.topBook = data[i].book?.topBook ?? false;
      item.lastReadAt = data[i].lastReadAt ?? 0;
      item.quiz = data[i].book?.quiz ?? false;
      item.quizAvailable = data[i].quizAvailable ?? false;
      item.quizCount = data[i].quizCount ?? 0;
      item.quizLinkUrl = data[i].book?.quizLinkUrl ?? '';
      //api5
      item.color = data[i].book?.color ?? '#808080';
      item.bookLevel = data[i].book?.bookLevel ?? '';
      // item.color = data[i].book?.level?.color ?? '#808080';
      // item.bookLevel = data[i].book?.level?.levelCode ?? '';
      item.pass = data[i].pass ?? false;
      item.readProgress = data[i].readProgress ?? 0;
      item.readComplete = data[i].readComplete ?? false;
      item.inFolder = data[i].inFolder ?? false;
      item.inAudioPlaylist = data[i].inAudioPlaylist ?? false;
      item.traditionalTitle = data[i].book?.traditionalTitle ?? '';
      item.viewMode = data[i].book?.viewMode;
      if (items.where((element) => element.bookId == item.bookId).length == 0) {
        items.add(item);
        bookCodes.add(item.bookCode.toString());
      }
      if (this
          ._selectedLeveledReadingBookItems
          .where((element) => element.bookId == item.bookId)
          .isNotEmpty) {
        item.selected = true;
      }
    }
    if (init) {
      _leveledReadingBookItems.assignAll(items);
    } else {
      _leveledReadingBookItems.addAll(items);
    }

    if (_leveledReadingBookItems.length > 0) {
      change(_leveledReadingBookItems, status: RxStatus.success());
      checkBookKnowledgesStatus(bookCodes, NanhaiBookReadingTypes.leveled);
    } else {
      change(null, status: RxStatus.empty());
    }
  }

  void setProgressReadingItems(int limit, int page) async {
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider.searchProgressreadingBooks(
          limit, page, this.dto);
      if (response.statusCode == 200) {
        List<ProgressReadingBook> data =
            progressReadingBooksFromJson(response.bodyString);
        setProgressReadingDataItems(data, true);
      } else {
        //change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
        change(null, status: RxStatus.empty());
      }
    } catch (e) {
    } finally {
      EasyLoading.dismiss();
    }
  }

  void fetchProgressReadingItems(int limit, int page) async {
    setCurrentPage(page);
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider
          .getProgressReadingBooksTotalNumber(this.dto);
      if (response.statusCode == 200) {
        var data =
            LeveledBookNumberResult.fromJson(json.decode(response.bodyString));
        leveledBooksTotalNum.value =
            data.count != null ? data.count!.toInt() : 0;
        setProgressReadingItems(limit, page);
      }
    } catch (error) {
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  // load more indead of pagination
  void fetchMoreLevelReadingItems() async {
    try {
      EasyLoading.show();
      if (Constants.pageLimit * (this._currentPage + 1) <
          leveledBooksTotalNum.value) {
        var response = await _bookServiceProvider.searchProgressreadingBooks(
            Constants.pageLimit, this._currentPage + 1, this.dto);
        if (response.statusCode == 200) {
          var data = progressReadingBooksFromJson(response.bodyString);
          setProgressReadingDataItems(data, false);
          this._currentPage = this._currentPage + 1;
        }
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void fetchProgressReadingItemsForChild(String userName) async {
    try {
      EasyLoading.show();
      List<String> bookCodes = [];
      var response = await _bookServiceProvider
          .searchProgressreadingBooksForChild(userName, this.dto);
      if (response.statusCode == 200) {
        List<BookItem> items = [];
        List<ProgressReadingBook> data =
            progressReadingBooksFromJson(response.bodyString);
        // getLeveledBooksTotalNumber();
        var _language = box.get('UserLanguage') ?? 'Simplified';
        for (int i = 0; i < data.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data[i].book?.bookCode ?? '';
          item.audio = data[i].book?.audio ?? '';
          item.bookId = data[i].book?.bookId ?? '';
          item.bilingual = data[i].book?.bilingual ?? false;
          item.bookContentLink = data[i].book?.bookContentLink ?? '';
          // item.bookImageLink = data[i].book?.bookImageLink ?? '';
          // item.bookTitle = data[i].book?.bookTitle ?? '';
          item.simBookImageLink = data[i].book?.bookImageLink ?? '';
          // final box = Hive.box('appconfig');
          // var _language = box.get('UserLanguage') ?? 'Simplified';
          if (_language == 'Traditional') {
            item.bookTitle = data[i].book?.traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
            // Log.debug(insertCharAt(item.simBookImageLink!,
            //     item.simBookImageLink!.length - 4, "t"));
          } else {
            item.bookTitle = data[i].book?.bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          item.description = data[i].book?.description ?? item.bookTitle;
          item.newArival = data[i].book?.newArival ?? false;
          item.topBook = data[i].book?.topBook ?? false;
          item.lastReadAt = data[i].lastReadAt ?? 0;
          item.quiz = data[i].book?.quiz ?? false;
          item.quizAvailable = data[i].quizAvailable ?? false;
          item.quizCount = data[i].quizCount ?? 0;
          item.quizLinkUrl = data[i].book?.quizLinkUrl ?? '';
          //api5
          item.color = data[i].book?.color ?? '#808080';
          item.bookLevel = data[i].book?.bookLevel ?? '';
          item.pass = data[i].pass ?? false;
          // item.color = data[i].book?.level?.color ?? '#808080';
          // item.bookLevel = data[i].book?.level?.levelCode ?? '';
          //item.pass = data[i].maxScore?.pass ?? false;
          item.readProgress = data[i].readProgress ?? 0;
          item.readComplete = data[i].readComplete ?? false;
          item.inFolder = data[i].inFolder ?? false;
          item.inAudioPlaylist = data[i].inAudioPlaylist ?? false;
          item.traditionalTitle = data[i].book?.traditionalTitle ?? '';
          item.viewMode = data[i].book?.viewMode;
          if (items.where((element) => element.bookId == item.bookId).length ==
              0) {
            items.add(item);
            bookCodes.add(item.bookCode.toString());
          }
        }
        _searchedBookItems.assignAll(items);
        if (_searchedBookItems.length > 0) {
          change(_searchedBookItems, status: RxStatus.success());
        } else {
          change(null, status: RxStatus.empty());
        }
      } else {
        //change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
        change(null, status: RxStatus.empty());
      }
    } catch (e) {
    } finally {
      EasyLoading.dismiss();
    }
  }

  Future<dynamic> fetchProgressReadingHistory(int limit, int page) async {
    List<BookItem> items = [];
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider.searchProgressreadingBooks(
          limit, page, this.dto);
      if (response.statusCode == 200) {
        List<ProgressReadingBook> data =
            progressReadingBooksFromJson(response.bodyString);
        // getLeveledBooksTotalNumber();
        var _language = box.get('UserLanguage') ?? 'Simplified';
        for (int i = 0; i < data.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data[i].book?.bookCode ?? '';
          item.audio = data[i].book?.audio ?? '';
          item.bookId = data[i].book?.bookId ?? '';
          item.bilingual = data[i].book?.bilingual ?? false;
          item.bookContentLink = data[i].book?.bookContentLink ?? '';
          // item.bookImageLink = data[i].book?.bookImageLink ?? '';
          // item.bookTitle = data[i].book?.bookTitle ?? '';
          item.simBookImageLink = data[i].book?.bookImageLink ?? '';
          // final box = Hive.box('appconfig');
          // var _language = box.get('UserLanguage') ?? 'Simplified';
          if (_language == 'Traditional') {
            item.bookTitle = data[i].book?.traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
            // Log.debug(insertCharAt(item.simBookImageLink!,
            //     item.simBookImageLink!.length - 4, "t"));
          } else {
            item.bookTitle = data[i].book?.bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          item.description = data[i].book?.description ?? item.bookTitle;
          item.newArival = data[i].book?.newArival ?? false;
          item.topBook = data[i].book?.topBook ?? false;
          item.lastReadAt = data[i].lastReadAt ?? 0;
          item.quiz = data[i].book?.quiz ?? false;
          item.quizAvailable = data[i].quizAvailable ?? false;
          item.quizCount = data[i].quizCount ?? 0;
          item.quizLinkUrl = data[i].book?.quizLinkUrl ?? '';
          //api5
          item.color = data[i].book?.color ?? '#808080';
          item.bookLevel = data[i].book?.bookLevel ?? '';
          // item.color = data[i].book?.level?.color ?? '#808080';
          // item.bookLevel = data[i].book?.level?.levelCode ?? '';
          item.pass = data[i].pass ?? false;
          item.readProgress = data[i].readProgress ?? 0;
          item.readComplete = data[i].readComplete ?? false;
          item.inFolder = data[i].inFolder ?? false;
          item.inAudioPlaylist = data[i].inAudioPlaylist ?? false;
          item.traditionalTitle = data[i].book?.traditionalTitle ?? '';
          item.viewMode = data[i].book?.viewMode;
          if (items.where((element) => element.bookId == item.bookId).length ==
              0) {
            items.add(item);
          }
        }
      }
    } catch (e) {
    } finally {
      EasyLoading.dismiss();
    }
    return items;
  }

  void fetchNewBooksItems() async {
    try {
      //change(_newBookItems, status: RxStatus.loading());
      var response = await _bookServiceProvider.getNewBooks();
      if (response.statusCode == 200) {
        List<BookItem> items = [];
        List<NewBook> data = newBookFromJson(response.bodyString);
        var _language = box.get('UserLanguage') ?? 'Simplified';
        for (int i = 0; i < data.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data[i].bookCode ?? '';
          item.audio = data[i].audio ?? '';
          item.bookId = data[i].bookId ?? '';
          item.bilingual = data[i].bilingual ?? false;
          item.bookContentLink = data[i].bookContentLink ?? '';
          // item.bookImageLink = data[i].bookImageLink ?? '';
          // item.bookTitle = data[i].bookTitle ?? '';
          item.simBookImageLink = data[i].bookImageLink ?? '';
          // final box = Hive.box('appconfig');
          // var _language = box.get('UserLanguage') ?? 'Simplified';
          if (_language == 'Traditional') {
            item.bookTitle = data[i].traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
            // Log.debug(insertCharAt(item.simBookImageLink!,
            //     item.simBookImageLink!.length - 4, "t"));
          } else {
            item.bookTitle = data[i].bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          //Log.debug('---11 title in controller-----${item.bookTitle}');
          item.description = data[i].description ?? item.bookTitle;
          item.newArival = data[i].newArival ?? false;
          item.topBook = data[i].topBook ?? false;
          item.quiz = data[i].quiz ?? false;
          item.quizLinkUrl = data[i].quizLinkUrl ?? '';
          item.color = data[i].level?.color ?? '#808080';
          item.bookLevel = data[i].level?.levelCode ?? '';
          item.viewMode = data[i].viewMode;
          //item.traditionalTitle = data[i].traditionalTitle ?? '';

          if (items.where((element) => element.bookId == item.bookId).length ==
              0) items.add(item);
        }
        _newBookItems.assignAll(items);
        change(_newBookItems, status: RxStatus.success());
      } else {
        change(_newBookItems,
            status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(_newBookItems,
          status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    }
  }

  void fetchMostReadBooksItems() async {
    try {
      var response = await _bookServiceProvider.getMostReadBooks();
      if (response.statusCode == 200) {
        MostReadBooksResult data = mostReadBooksResultFromJson(response.body);
        List<MostReadBook> mrBooks = data.result!.subResult ?? <MostReadBook>[];
        List<BookItem> items = [];
        var _language = box.get('UserLanguage') ?? 'Simplified';
        for (int i = 0; i < mrBooks.length; i++) {
          BookItem item = BookItem();
          item.bookImageLink = mrBooks[i].imageLink ?? '';
          if (_language == 'Simplified') {
            item.bookTitle = mrBooks[i].bookTitle ?? '';
          } else {
            item.bookTitle = mrBooks[i].traditionalTitle ?? '';
          }
          // item.bookTitle = mrBooks[i].bookTitle ?? '';
          // item.traditionalTitle = mrBooks[i].traditionalTitle ?? '';
          item.bookId = mrBooks[i].id ?? '';
          item.bookCode = mrBooks[i].bookCode ?? '';
          item.bookLevel = mrBooks[i].bookLevel ?? '';
          if (items.where((element) => element.bookId == item.bookId).length ==
              0) items.add(item);
        }
        _mostReadBookItems.assignAll(items);
        change(_mostReadBookItems, status: RxStatus.success());
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    }
  }

  void fetchMostReadBooksItemsSchool() async {
    try {
      var response = await _bookServiceProvider.getSchoolMostReadBooks();
      if (response.statusCode == 200) {
        List<BookItem> items = [];
        var _language = box.get('UserLanguage') ?? 'Simplified';
        MostReadBooksResult data = mostReadBooksResultFromJson(response.body);
        List<MostReadBook> mrBooks = data.result!.subResult ?? <MostReadBook>[];
        for (int i = 0; i < mrBooks.length; i++) {
          BookItem item = BookItem();
          item.bookImageLink = mrBooks[i].imageLink ?? '';
          if (_language == 'Simplified') {
            item.bookTitle = mrBooks[i].bookTitle ?? '';
          } else {
            item.bookTitle = mrBooks[i].traditionalTitle ?? '';
          }
          // item.bookTitle = mrBooks[i].bookTitle ?? '';
          // item.traditionalTitle = mrBooks[i].traditionalTitle ?? '';
          item.bookId = mrBooks[i].id ?? '';
          item.bookCode = mrBooks[i].bookCode ?? '';
          item.bookLevel = mrBooks[i].bookLevel ?? '';
          if (items.where((element) => element.bookId == item.bookId).length ==
              0) items.add(item);
        }
        _mostReadBookItemsSchool.assignAll(items);
        change(_mostReadBookItemsSchool, status: RxStatus.success());
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    }
  }

  void setMyFavoriteReadingItemsByFolder(data, init) {
    List<String> bookCodes = [];
    List<String> bookIds = [];
    List<BookItem> items = [];
    //final box = Hive.box('appconfig');
    var _language = box.get('UserLanguage') ?? 'Simplified';
    for (int i = 0; i < data.list!.length; i++) {
      BookItem item = BookItem();
      item.bookCode = data.list?[i].book?.bookCode ?? '';
      item.audio = data.list?[i].book?.audio ?? '';
      item.bookId = data.list?[i].book?.bookId ?? '';
      item.bilingual = data.list?[i].book?.bilingual ?? false;
      item.bookContentLink = data.list?[i].book?.bookContentLink ?? '';
      item.simBookImageLink = data.list?[i].book?.bookImageLink ?? '';
      if (_language == 'Traditional') {
        item.bookTitle = data.list?[i].book?.traditionalTitle ?? '';
        item.bookImageLink = StrUtil.insertCharAt(
                item.simBookImageLink!, item.simBookImageLink!.length - 4, "t")
            .replaceAll('.gif', '.jpg');
      } else {
        item.bookTitle = data.list?[i].book?.bookTitle ?? '';
        item.bookImageLink = item.simBookImageLink;
      }
      item.description = data.list?[i].book?.description ?? item.bookTitle;
      item.newArival = data.list?[i].book?.newArival ?? false;
      item.topBook = data.list?[i].book?.topBook ?? false;
      item.quiz = data.list?[i].book?.quiz ?? false;
      item.quizLinkUrl = data.list?[i].book?.quizLinkUrl ?? '';
      item.quizAvailable = data.list?[i].quizAvailable ?? false;
      //api5
      item.color = data.list![i].book?.color ?? '#808080';
      item.bookLevel = data.list![i].book?.bookLevel ?? '';
      item.readComplete = data.list?[i].readComplete ?? false;
      item.pass = data.list?[i].pass ?? false;
      item.inFolder = data.list?[i].inFolder ?? false;
      item.inAudioPlaylist = data.list?[i].inAudioPlaylist ?? false;
      item.traditionalTitle = data.list![i].book?.traditionalTitle ?? '';
      item.viewMode = data.list![i].book?.viewMode;
      if (items.where((element) => element.bookId == item.bookId).length == 0) {
        items.add(item);
        bookCodes.add(item.bookCode.toString());
        bookIds.add(item.bookId.toString());
      }
    }
    if (init) {
      _myFavoriteBookItems.assignAll(items);
    } else {
      _myFavoriteBookItems.addAll(items);
    }
    change(_selectedFavoriteReadingBookItems, status: RxStatus.success());
    if (_myFavoriteBookItems.length > 0) {
      change(_myFavoriteBookItems, status: RxStatus.success());
      bool isTeacher = box.get(CacheManagerKey['nanhairole'].toString()) ==
          Constants.NanhaiRole_Teacher;
      if (isTeacher) {
        var _classId = box.get(CacheManagerKey['currentclass'].toString());
        checkBookAssignmentStatus(
            _classId, bookIds, NanhaiBookReadingTypes.favorite);
      } else {
        bool isStudentOrIndividual =
            box.get(CacheManagerKey['nanhairole'].toString()) ==
                    Constants.NanhaiRole_Student ||
                box.get(CacheManagerKey['nanhairole'].toString()) ==
                    Constants.NanhaiRole_Individual;
        if (isStudentOrIndividual) {
          checkBookKnowledgesStatus(bookCodes, NanhaiBookReadingTypes.favorite);
        }
      }
    } else {
      change(null, status: RxStatus.empty());
    }
  }

  void fetchMyFavoriteReadingItemsByFolder(String foldId) async {
    setCurrentPage(0);
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider.getMyLibraryBooksByFoldId(
          foldId, Constants.pageLimit, 0);
      if (response.statusCode == 200) {
        FolderBookListResult data =
            folderBookListResultFromJson(response.bodyString);
        libraryBooksTotalNum.value = data.count!;
        setMyFavoriteReadingItemsByFolder(data, true);
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void fetchMoreMyFavoriteReadingItemsByFolder() async {
    try {
      EasyLoading.show();
      if (Constants.pageLimit * (this._currentPage + 1) <
          libraryBooksTotalNum.value) {
        var response = await _bookServiceProvider.getMyLibraryBooksByFoldId(
            _currentBookFolder.value.id ?? 'ROOTFOLDER',
            Constants.pageLimit,
            this._currentPage + 1);
        if (response.statusCode == 200) {
          FolderBookListResult data =
              folderBookListResultFromJson(response.bodyString);
          setMyFavoriteReadingItemsByFolder(data, false);
          this._currentPage = this._currentPage + 1;
        }
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  void fetchChildFavoriteReadingItemsByFolder(
      String foldId, String userName) async {
    try {
      EasyLoading.show();
      List<String> bookCodes = [];
      List<String> bookIds = [];
      var response = await _bookServiceProvider.getChildLibraryBooksByFoldId(
          foldId, userName);
      if (response.statusCode == 200) {
        List<BookItem> items = [];
        MyLibraryBooks data = myLibraryBooksFromJson(response.bodyString);
        var _language = box.get('UserLanguage') ?? 'Simplified';
        if (data.books != null) {
          for (int i = 0; i < data.books!.length; i++) {
            BookItem item = BookItem();
            item.bookCode = data.books?[i].book?.bookCode ?? '';
            item.audio = data.books?[i].book?.audio ?? '';
            item.bookId = data.books?[i].book?.bookId ?? '';
            item.bilingual = data.books?[i].book?.bilingual ?? false;
            item.bookContentLink = data.books?[i].book?.bookContentLink ?? '';
            item.simBookImageLink = data.books?[i].book?.bookImageLink ?? '';
            if (_language == 'Traditional') {
              item.bookTitle = data.books?[i].book?.traditionalTitle ?? '';
              item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                      item.simBookImageLink!.length - 4, "t")
                  .replaceAll('.gif', '.jpg');
              // Log.debug(insertCharAt(item.simBookImageLink!,
              //     item.simBookImageLink!.length - 4, "t"));
            } else {
              item.bookTitle = data.books?[i].book?.bookTitle ?? '';
              item.bookImageLink = item.simBookImageLink;
            }
            item.description =
                data.books?[i].book?.description ?? item.bookTitle;
            item.newArival = data.books?[i].book?.newArival ?? false;
            item.topBook = data.books?[i].book?.topBook ?? false;
            item.quiz = data.books?[i].book?.quiz ?? false;
            item.quizLinkUrl = data.books?[i].book?.quizLinkUrl ?? '';
            item.quizAvailable = data.books?[i].quizAvailable ?? false;
            // item.color = data.books?[i].book?.level?.color ?? '#808080';
            // item.bookLevel = data.books?[i].book?.level?.levelCode ?? '';
            //api5
            item.color = data.books![i].book?.color ?? '#808080';
            item.bookLevel = data.books![i].book?.bookLevel ?? '';
            item.readComplete = data.books?[i].readComplete ?? false;
            item.pass = data.books?[i].maxScore?.pass ?? false;
            item.inFolder = data.books?[i].inFolder ?? false;
            item.inAudioPlaylist = data.books?[i].inAudioPlaylist ?? false;
            item.traditionalTitle = data.books![i].book?.traditionalTitle ?? '';
            item.viewMode = data.books![i].book?.viewMode;
            if (items
                    .where((element) => element.bookId == item.bookId)
                    .length ==
                0) {
              items.add(item);
              bookCodes.add(item.bookCode.toString());
              bookIds.add(item.bookId.toString());
            }
          }
          _myFavoriteBookItems.assignAll(items);
        }
        if (_myFavoriteBookItems.length > 0) {
          change(_myFavoriteBookItems, status: RxStatus.success());
        } else {
          change(null, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  Future<List<AllFolder>> fetchBookAllFolders() async {
    try {
      var response = await _bookServiceProvider.getBookFolders();
      if (response.statusCode == 200) {
        BookFolders data =
            BookFolders.fromJson(json.decode(response.bodyString));
        if (data.allFolder != null && data.allFolder!.isNotEmpty) {
          var mainFolder = data.allFolder?[0];

          if (data.allFolder!.length > 1) {
            var folders = data.allFolder as List<AllFolder>;
            folders.removeAt(0);
            folders.sort((a, b) => a.folderName!.compareTo(b.folderName!));
            folders.insert(0, mainFolder as AllFolder);
            _bookFolders.assignAll(folders);
          } else {
            _bookFolders.assignAll(data.allFolder as List<AllFolder>);
          }

          if (this._currentBookFolder.value.id == null) {
            this._currentBookFolder.value = _bookFolders[0];
          } else {
            if (_bookFolders
                .where(
                    (element) => element.id == this._currentBookFolder.value.id)
                .isEmpty) {
              this._currentBookFolder.value = _bookFolders[0];
            }
          }
          change(_bookFolders, status: RxStatus.success());
        }
      }
    } catch (error) {
      Log.debug(error);
    }
    return _bookFolders;
  }

  Future<List<AllFolder>> fetchBookAllFoldersForChild(String userName) async {
    try {
      var response =
          await _bookServiceProvider.getBookFoldersForChild(userName);
      if (response.statusCode == 200) {
        BookFolders data =
            BookFolders.fromJson(json.decode(response.bodyString));
        if (data.allFolder != null && data.allFolder!.isNotEmpty) {
          var mainFolder = data.allFolder?[0];

          if (data.allFolder!.length > 1) {
            var folders = data.allFolder as List<AllFolder>;
            folders.removeAt(0);
            folders.sort((a, b) => a.folderName!.compareTo(b.folderName!));
            folders.insert(0, mainFolder as AllFolder);
            _bookFolders.assignAll(folders);
          } else {
            _bookFolders.assignAll(data.allFolder as List<AllFolder>);
          }

          if (this._currentBookFolder.value.id == null) {
            this._currentBookFolder.value = _bookFolders[0];
          } else {
            if (_bookFolders
                .where(
                    (element) => element.id == this._currentBookFolder.value.id)
                .isEmpty) {
              this._currentBookFolder.value = _bookFolders[0];
            }
          }
          change(_bookFolders, status: RxStatus.success());
        }
      }
    } catch (error) {
      Log.debug(error);
    }
    return _bookFolders;
  }

  void fetchBookAllFoldersByID(folderId) async {
    try {
      var response = await _bookServiceProvider.getBookFolders();
      if (response.statusCode == 200) {
        BookFolders data =
            BookFolders.fromJson(json.decode(response.bodyString));

        if (data.allFolder != null && data.allFolder!.isNotEmpty) {
          _bookFolders.assignAll(data.allFolder as List<AllFolder>);
          var contain = false;
          AllFolder folder = _bookFolders[0];
          for (var i = 0; i < _bookFolders.length; i++) {
            if (_bookFolders[i].id == folderId) {
              contain = true;
              folder = _bookFolders[i];
              setCurrentBookFolder(folder);
              break;
            }
          }
          if (!contain) {
            setCurrentBookFolder(_bookFolders[0]);
          }
          change(_bookFolders, status: RxStatus.success());
        }
      }
    } catch (error) {
      Log.debug(error);
    }
  }

// 调用后可以直接通过 bookFolders 获得更新的目录
  void addBookLibraryFolder(String folderName) async {
    try {
      var response = await _bookServiceProvider.addLibraryFolder(folderName);
      StatusMessageResult data =
          statusMessageResultFromJson(response.bodyString);
      _statusMessageResult.value = data;
      if (response.statusCode == 200) {
        fetchBookAllFolders();
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  Future<StatusMessageResult> createBookLibraryFolder(String folderName) async {
    var data = StatusMessageResult();
    try {
      var response = await _bookServiceProvider.addLibraryFolder(folderName);
      if (response.statusCode == 200) {
        fetchBookAllFolders();
        data = statusMessageResultFromJson(response.bodyString);
      }
    } catch (error) {
      Log.debug(error);
    }
    return data;
  }

  void addBookLibraryFolderAndBooks(
      String folderName, List<String> bookIds, String readingTypeFrom) async {
    try {
      var response = await _bookServiceProvider.addLibraryFolder(folderName);
      if (response.statusCode == 200) {
        fetchBookAllFolders();
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  void setCurrentBookFolder(AllFolder myFolder) async {
    try {
      this._currentBookFolder.value = myFolder;
    } catch (error) {
      Log.debug(error);
    }
  }

  AllFolder getCurrentBookFolder() {
    try {
      return this._currentBookFolder.value;
    } catch (error) {
      Log.debug(error);
      return new AllFolder();
    }
  }

  void setCurrentPage(page) async {
    try {
      this._currentPage = page;
    } catch (error) {
      Log.debug(error);
    }
  }

  void setCurrentPageLimit(page) async {
    try {
      this._currentPageLimit = page;
    } catch (error) {
      Log.debug(error);
    }
  }

  void setBookSearchDto(dto) async {
    try {
      this.dto = dto;
      //print(bookSearchDtoToJson(this.dto));
    } catch (error) {
      Log.debug(error);
    }
  }

  BookSearchDto getBookSearchDeto() {
    return this.dto;
  }

  void setLevelOptions(levelOptions) async {
    try {
      this._levelOptions = levelOptions;
    } catch (error) {
      Log.debug(error);
    }
  }

  void getAllBookFolders() async {
    try {
      var response = await _bookServiceProvider.getBookFolders();
      if (response.statusCode == 200) {
        BookFolders data =
            BookFolders.fromJson(json.decode(response.bodyString));
        if (data.allFolder != null && data.allFolder!.isNotEmpty) {
          allBookFolders = data.allFolder as List<AllFolder>;
        }
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  ///updateLibraryFolderName
  Future<StatusMessageResult> updateLibraryFolderName(
      String folderId, String newFolderName) async {
    var data = new StatusMessageResult();
    try {
      var response = await _bookServiceProvider.updateLibraryFolderName(
          folderId, newFolderName);
      //setCurrentBookFolder(AllFolder myFolder)
      data = statusMessageResultFromJson(response.bodyString);
      Log.debug('${response.status}');
      if (response.statusCode == 200) {
        fetchBookAllFoldersByID(folderId);
      }
    } catch (error) {
      Log.debug(error);
    }
    return data;
  }

  Future<StatusMessageResult> deleteBookLibraryFolder(String folderId) async {
    var data = StatusMessageResult();
    try {
      var response = await _bookServiceProvider.deleteLibraryFolder(folderId);
      if (response.statusCode == 200) {
        data.status = 1000;
        data.message = 'Deleted successfully!';
        this._bookFolders.removeWhere((element) => element.id == folderId);
        this._currentBookFolder.value = this._bookFolders[0];
        change(this._bookFolders, status: RxStatus.success());
      } else {
        data.status = 0;
        data.message = 'Failed to delete';
      }
    } catch (error) {
      Log.debug(error);
      data.status = 0;
      data.message = 'Failed to delete';
    }
    return data;
  }

  Future<StatusMessageResult> addBooksToLibraryFolder(String folderId,
      List<String> bookIds, NanhaiBookReadingTypes readingTypeFrom) async {
    var data = StatusMessageResult();
    try {
      var response = await _bookServiceProvider.addBookItemsToLibraryFolder(
          folderId, bookIds);
      data = statusMessageResultFromJson(response.bodyString);

      Log.debug('${response.status}');
      if (response.statusCode == 200) {
        if (readingTypeFrom == NanhaiBookReadingTypes.library) {
          //fetchOpenReadingItems(this._currentPageLimit, this._currentPage);
          bookIds.forEach((bookId) {
            int index = this
                ._openLibraryReadingBookItems
                .indexWhere((book) => book.bookId == bookId);

            if (index != -1) {
              this
                  ._openLibraryReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inFolder = true;
              this
                  ._openLibraryReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._openLibraryReadingBookItems, status: RxStatus.success());
        }
        if (readingTypeFrom == NanhaiBookReadingTypes.leveled) {
          //fetchProgressReadingItems(this._currentPageLimit, this._currentPage);
          bookIds.forEach((bookId) {
            int index = this
                ._leveledReadingBookItems
                .indexWhere((book) => book.bookId == bookId);
            if (index != -1) {
              this
                  ._leveledReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inFolder = true;
              this
                  ._leveledReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._leveledReadingBookItems, status: RxStatus.success());
        }

        if (readingTypeFrom == NanhaiBookReadingTypes.favorite) {
          //fetchOpenReadingItems(this._currentPageLimit, this._currentPage);
          bookIds.forEach((bookId) {
            int index = this
                ._myFavoriteBookItems
                .indexWhere((book) => book.bookId == bookId);

            if (index != -1) {
              this
                  ._myFavoriteBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inFolder = true;
              this
                  ._myFavoriteBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._myFavoriteBookItems, status: RxStatus.success());
        }

        if (readingTypeFrom == NanhaiBookReadingTypes.assignment) {
          //fetchProgressReadingItems(this._currentPageLimit, this._currentPage);
          bookIds.forEach((bookId) {
            int index = this
                ._assignedBookItems
                .indexWhere((book) => book.bookId == bookId);
            if (index != -1) {
              this
                  ._assignedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inFolder = true;
              this
                  ._assignedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._assignedBookItems, status: RxStatus.success());
        }

        if (readingTypeFrom == NanhaiBookReadingTypes.search) {
          //fetchProgressReadingItems(this._currentPageLimit, this._currentPage);
          bookIds.forEach((bookId) {
            int index = this
                ._searchedBookItems
                .indexWhere((book) => book.bookId == bookId);
            if (index != -1) {
              this
                  ._searchedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inFolder = true;
              this
                  ._searchedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._searchedBookItems, status: RxStatus.success());
        }
        if (readingTypeFrom == NanhaiBookReadingTypes.evaluation) {
          //fetchProgressReadingItems(this._currentPageLimit, this._currentPage);
          bookIds.forEach((bookId) {
            int index = this
                ._evaluationBookItems
                .indexWhere((book) => book.bookId == bookId);
            if (index != -1) {
              this
                  ._evaluationBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inFolder = true;
              this
                  ._evaluationBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._evaluationBookItems, status: RxStatus.success());
        }
        if (readingTypeFrom == NanhaiBookReadingTypes.theme) {
          bookIds.forEach((bookId) {
            int index = this
                ._themedBookItems
                .indexWhere((book) => book.bookId == bookId);
            if (index != -1) {
              this
                  ._themedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inFolder = true;
              this
                  ._themedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._themedBookItems, status: RxStatus.success());
        }

        if (readingTypeFrom == NanhaiBookReadingTypes.textbook) {
          if (this._programBookList.isNotEmpty &&
              this._selectedTextBookItems.isNotEmpty) {
            _iterateProgrambooksTree(
                this._programBookList, this._selectedTextBookItems);
          }
          //this._selectedTextBookItems.clear();
          //change(this._selectedTextBookItems, status: RxStatus.success());
          change(this._programBookList, status: RxStatus.success());
        }
      }
    } catch (error) {
      Log.debug(error);
    }
    return data;
  }

  void _iterateProgrambooksTree(
      List<ProgramBookList> inDatatree, List<BookItem> inbooks) {
    if (inDatatree.isNotEmpty) {
      inDatatree.forEach((tree) {
        if (tree.bookList != null && tree.bookList!.isNotEmpty) {
          inbooks.forEach((book) {
            if (tree.bookList!
                .where((element) => element.bookId == book.bookId)
                .isNotEmpty) {
              //Log.debug(book.bookId);
              tree.bookList!
                  .where((element) => element.bookId == book.bookId)
                  .first
                  .inFolder = true;
              if (this
                  ._selectedTextBookItems
                  .where((element) => element.bookId == book.bookId)
                  .isNotEmpty) {
                // this
                //     ._selectedTextBookItems
                //     .where((element) => element.bookId == book.bookId)
                //     .first
                //     .selected = false;
              }
            }
          });
        }
        if (tree.lowerProgram != null && tree.lowerProgram!.isNotEmpty) {
          _iterateProgrambooksTree(
              tree.lowerProgram as List<ProgramBookList>, inbooks);
        }
      });
    }
  }

  Future<StatusMessageResult> removeBooksFromLibraryFolder(
      String folderId, List<String> bookIds) async {
    var data = StatusMessageResult();
    EasyLoading.show();
    try {
      var response = await _bookServiceProvider
          .deleteBookItemsFromLibraryFolder(folderId, bookIds);

      if (response.statusCode == 200) {
        data.status = 1000;
        data.message = 'Book(s) removed from lesson plan / folder';

        fetchBookAllFoldersByID(getCurrentBookFolder().id);

        if (bookIds.isNotEmpty) {
          bookIds.forEach((bookId) {
            this
                ._myFavoriteBookItems
                .removeWhere((element) => element.bookId == bookId);
          });
          change(this.myFavoriteBookItems, status: RxStatus.success());
        }
      }
    } catch (error) {
      data.status = 0;
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
    return data;
  }

////// audio play list
  ///
  void fetchAudioPlayBooksItems() async {
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider.getAudioBookListResult();
      if (response.statusCode == 200) {
        var data = audiobooksPlayListResultFromJson(response.bodyString);
        final box = Hive.box('appconfig');
        var _language = box.get('UserLanguage') ?? 'Simplified';
        if (data.booksProgress != null) {
          Log.debug(data.booksProgress!.length);
          List<BookItem> items = [];
          for (int i = 0; i < data.booksProgress!.length; i++) {
            BookItem item = BookItem();
            item.bookCode = data.booksProgress![i].book?.bookCode ?? '';
            item.audio = data.booksProgress![i].book?.audio ?? '';
            item.bookId = data.booksProgress![i].book?.bookId ?? '';
            item.bilingual = data.booksProgress![i].book?.bilingual ?? false;
            item.bookContentLink =
                data.booksProgress![i].book?.bookContentLink ?? '';
            item.simBookImageLink =
                data.booksProgress![i].book?.bookImageLink ?? '';
            if (_language == 'Traditional') {
              item.bookTitle =
                  data.booksProgress![i].book?.traditionalTitle ?? '';
              item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                      item.simBookImageLink!.length - 4, "t")
                  .replaceAll('.gif', '.jpg');
            } else {
              item.bookTitle = data.booksProgress![i].book?.bookTitle ?? '';
              item.bookImageLink = item.simBookImageLink;
            }
            item.description =
                data.booksProgress![i].book?.description ?? item.bookTitle;
            item.newArival = data.booksProgress![i].book?.newArival ?? false;
            item.topBook = data.booksProgress![i].book?.topBook ?? false;
            item.quiz = data.booksProgress![i].book?.quiz ?? false;
            item.quizLinkUrl = data.booksProgress![i].book?.quizLinkUrl ?? '';
            item.viewMode = data.booksProgress![i].book?.viewMode;
            if (items
                    .where((element) => element.bookId == item.bookId)
                    .length ==
                0) items.add(item);
          }
          // //take only 20 since loading speed is slow
          // _audioPlayBookItems.assignAll(items.take(20));
          _audioPlayBookItems.assignAll(items);
          if (_audioPlayBookItems.length > 0)
            change(_audioPlayBookItems, status: RxStatus.success());
          else
            change(null, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
  }

  Future<StatusMessageResult> addBooksToAudioPlaylist(
      List<String> bookIds, String readingTypeFrom) async {
    var data = StatusMessageResult();
    EasyLoading.show();
    try {
      var response =
          await _bookServiceProvider.addBooksToAudioPlaylist(bookIds);
      if (response.statusCode == 200) {
        // there is no response body
        data.status = 1000;
        data.message = 'Add to audio folder seccessfully'.tr;
        if (readingTypeFrom == "library") {
          bookIds.forEach((bookId) {
            if (this
                ._openLibraryReadingBookItems
                .where((book) => book.bookId == bookId)
                .isNotEmpty) {
              this
                  ._openLibraryReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inAudioPlaylist = true;
              this
                  ._openLibraryReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._openLibraryReadingBookItems, status: RxStatus.success());
        }
        if (readingTypeFrom == "leveled") {
          bookIds.forEach((bookId) {
            if (this
                ._leveledReadingBookItems
                .where((book) => book.bookId == bookId)
                .isNotEmpty) {
              this
                  ._leveledReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inAudioPlaylist = true;
              this
                  ._leveledReadingBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._leveledReadingBookItems, status: RxStatus.success());
        }

        if (readingTypeFrom == "search") {
          bookIds.forEach((bookId) {
            if (this
                ._searchedBookItems
                .where((book) => book.bookId == bookId)
                .isNotEmpty) {
              this
                  ._searchedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inAudioPlaylist = true;
              this
                  ._searchedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._searchedBookItems, status: RxStatus.success());
        }

        if (readingTypeFrom == "assignment") {
          bookIds.forEach((bookId) {
            if (this
                ._assignedBookItems
                .where((book) => book.bookId == bookId)
                .isNotEmpty) {
              this
                  ._assignedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inAudioPlaylist = true;
              this
                  ._assignedBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this._assignedBookItems, status: RxStatus.success());
        }

        if (readingTypeFrom == 'favorite') {
          bookIds.forEach((bookId) {
            if (this
                .myFavoriteBookItems
                .where((book) => book.bookId == bookId)
                .isNotEmpty) {
              this
                  .myFavoriteBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .inAudioPlaylist = true;
              this
                  .myFavoriteBookItems
                  .where((book) => book.bookId == bookId)
                  .first
                  .selected = false;
            }
          });
          change(this.myFavoriteBookItems, status: RxStatus.success());
        }
      }
    } catch (error) {
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
    return data;
  }

  Future<StatusMessageResult> deleteBooksFromAudioPlaylist(
      String bookId) async {
    var _statusMessageResult = StatusMessageResult();
    EasyLoading.show();
    try {
      var response =
          await _bookServiceProvider.removeBooksFromAudioPlaylist(bookId);
      if (response.statusCode == 200) {
        _statusMessageResult.status = 1000;
        _statusMessageResult.message = 'Delete audio playlist seccessfully'.tr;

        this
            ._audioPlayBookItems
            .removeWhere((element) => element.bookId == bookId);
        change(_audioPlayBookItems, status: RxStatus.success());
      }
    } catch (error) {
      _statusMessageResult.status = 0;
      _statusMessageResult.message = 'Error to delete audio playlist!'.tr;
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
    return _statusMessageResult;
  }

///// for school admin book summary report
  void getBooksDataSummary() async {
    try {
      var response = await _bookServiceProvider.getBooksDataSummary();
      if (response.statusCode == 200) {
        BooksDataSummaryResult data =
            booksDataSummaryResultFromJson(response.bodyString);
        _booksDataSummary.value = data;
        Map<String, int> mapdata = data.result?.level as Map<String, int>;
        Map<String, int> maptopics = data.result?.category as Map<String, int>;
        if (mapdata.length > 0) {
          _bookleveldata.clear();

          mapdata.forEach((k, v) {
            var lc = Constants.levelOptions
                .where((element) => element.label == k)
                .first;
            _bookleveldata.add(new BookChartData(
                k, v, hexStringToHexInt(lc.color.toString())));
          });
        }
        if (maptopics.length > 0) {
          _booktopicsdata.clear();
          maptopics.forEach((k, v) {
            _booktopicsdata.add(new BookChartData(k, v, null));
          });
        }
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  void fetchBooksDataSummary() async {
    try {
      var response = await _bookServiceProvider.getBooksDataSummary();
      if (response.statusCode == 200) {
        BooksDataSummaryResult data =
            booksDataSummaryResultFromJson(response.bodyString);
        this._booksDataSummary.value = data;
        change(this._booksDataSummary, status: RxStatus.success());
      }
    } catch (error) {
      change(this._booksDataSummary, status: RxStatus.error());
      Log.debug(error);
    }
  }

////////
  void getBooksFilters() async {
    try {
      var response = await _bookServiceProvider.getBooksFilters();
      //Log.debug(response);
      //Log.debug(json.decode(utf8.decode(response.bodyBytes)));
      if (response.statusCode == 200) {
        _bookfilters.assignAll(
            bookFiltersFromJson(utf8.decode(response.bodyBytes)).children
                as List<BookFilter>);
      }
    } catch (error) {
      Log.debug(error);
    }
  }

//////
  void getAllBookCategorySeries() async {
    try {
      var response = await _bookServiceProvider.getBookCategorySeries();
      if (response.statusCode == 200) {
        var data = categoryForSeriesFromJson(response.bodyString);
        this._bookCategorySeries.assignAll(data);
      }
    } catch (error) {
      Log.debug(error);
    }
  }

/////https://itnext.io/write-your-first-web-scraper-in-dart-243c7bb4d05
  void getBookFullText(String bookCode, bool simplified) async {
    try {
      change(_bookFullText, status: RxStatus.loading());
      var _language = box.get('UserLanguage') ?? 'Simplified';
      if (_language == 'Simplified') {
        simplified = true;
      } else {
        simplified = false;
      }
      var response = await _bookServiceProvider.getBookFullHtmlText(bookCode);
      var document = parse(utf8.decode(response.bodyBytes));
      var nodesToRemove = document.querySelectorAll("ruby>rt");
      if (nodesToRemove.isNotEmpty) {
        nodesToRemove.forEach((node) {
          node.remove();
        });
      }
      var htmlNodes = [];
      if (simplified)
        htmlNodes = document.getElementsByClassName('text simp-p chfont');
      else
        htmlNodes = document.getElementsByClassName('text trad-p trfont');

      String _fulltext = '';

      if (htmlNodes.isNotEmpty) {
        htmlNodes.forEach((html) {
          var node = html as Element;
          _fulltext += '${node.outerHtml} <br />';
        });
        // htmlNodes.forEach((html) {
        //   var node = html as Element;
        //   _fulltext += '${node.text.toString()} \n';
        // });
        // this._bookFullText.value = _fulltext
        //     .replaceAll("&#8288;", "")
        //     .replaceAll("&#8203;", "")
        //     .replaceAll("\"", "'")
        //     .replaceAll("⁠", "");
        this._bookFullText.value = _fulltext;
        change(_bookFullText, status: RxStatus.success());
      } else
        this._bookFullText.value = 'Text not available'.tr;
      change(_bookFullText, status: RxStatus.success());
    } catch (error) {
      Log.debug(error);
      this._bookFullText.value = 'Text not available'.tr;
    }
  }

  void setLevel(level) async {
    try {
      this._level = level;
    } catch (error) {
      Log.debug(error);
    }
  }

  void setProgress(progress) async {
    try {
      this._progress = progress;
    } catch (error) {
      Log.debug(error);
    }
  }

  // void refreshLevelPercentage() async {
  //   try {
  //     var response = await _bookServiceProvider.refreshLevelPercentage();
  //     if (response.statusCode == 200) {
  //       var data = response.bodyString;
  //       setProgress(json.decode(data)['levelPercentage'].toString());
  //       setLevel(
  //           json.decode(data)['levelDisplayName'].replaceAll('Level ', ''));
  //       //this._bookCategorySeries.assignAll(data);
  //     }
  //   } catch (error) {
  //     Log.debug(error);
  //   }
  // }

  void getBookRecordingFile(bookId, assignmentId) async {
    try {
      var response =
          await _bookServiceProvider.getRecording(bookId, assignmentId);
      if (response.statusCode == 200) {
        var data = recordLocationFromJson(response.bodyString);
        String? fileId = data.location;
        if (fileId != '' && fileId != null) {
          response = await _bookServiceProvider.downloadFileLocationg(fileId);
          // Log.debug(
          //     'from server--location----${jsonDecode(response.bodyString)['location']}');
          _bookRecordingLocation.value =
              jsonDecode(response.bodyString)['location'];
          change(_bookRecordingLocation, status: RxStatus.success());
        } else {
          this._bookRecordingLocation.value = '';
          change(_bookRecordingLocation, status: RxStatus.success());
        }
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  void setBookRecordingState(bool isRecording) {
    this._isRecording.value = isRecording;
  }

  void getNewBooksDataForDays(int days) async {
    try {
      var response = await _bookServiceProvider.getNewBooksDataForDays(days);
      if (response.statusCode == 200) {
        var data = bookReleaseFromJson(response.bodyString);
        this._bookRelease.value = data;
        var mapData = data.result;
        if (mapData!.length > 0) {
          _bookReleaseData.clear();
          mapData.forEach((k, v) {
            String date = k;
            var value = 0;
            v.forEach((element) {
              value++;
              BookReleaseItem book = element;
              _bookReleaseData.add(new BookReleaseChartData(date, book, value));
            });
          });
          _bookReleaseData
              .sort((a, b) => int.parse(a.date).compareTo(int.parse(b.date)));
        }
        change(this._bookRelease, status: RxStatus.success());
      }
    } catch (error) {
      change(this._bookRelease, status: RxStatus.error());
      Log.debug(error);
    }
  }

  void updateBookStatus(
      String bookId, NanhaiBookReadingTypes readingTypeFrom) async {
    if (readingTypeFrom == NanhaiBookReadingTypes.library) {
      if (this
          ._openLibraryReadingBookItems
          .where((book) => book.bookId == bookId)
          .isNotEmpty) {
        this
            ._openLibraryReadingBookItems
            .where((book) => book.bookId == bookId)
            .first
            .readComplete = true;
        this
            ._openLibraryReadingBookItems
            .where((book) => book.bookId == bookId)
            .first
            .selected = false;
      }
      change(this._openLibraryReadingBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == NanhaiBookReadingTypes.leveled) {
      if (this
          ._leveledReadingBookItems
          .where((book) => book.bookId == bookId)
          .isNotEmpty) {
        this
            ._leveledReadingBookItems
            .where((book) => book.bookId == bookId)
            .first
            .readComplete = true;
        this
            ._leveledReadingBookItems
            .where((book) => book.bookId == bookId)
            .first
            .selected = false;
      }
      change(this._leveledReadingBookItems, status: RxStatus.success());
    }

    if (readingTypeFrom == NanhaiBookReadingTypes.assignment) {
      if (this
          ._assignedBookItems
          .where((book) => book.bookId == bookId)
          .isNotEmpty) {
        this
            ._assignedBookItems
            .where((book) => book.bookId == bookId)
            .first
            .readComplete = true;
        this
            ._assignedBookItems
            .where((book) => book.bookId == bookId)
            .first
            .selected = false;
      }
      change(this._assignedBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == NanhaiBookReadingTypes.evaluation) {
      if (this
          ._evaluationBookItems
          .where((book) => book.bookId == bookId)
          .isNotEmpty) {
        this
            ._evaluationBookItems
            .where((book) => book.bookId == bookId)
            .first
            .readComplete = true;
        this
            ._evaluationBookItems
            .where((book) => book.bookId == bookId)
            .first
            .selected = false;
      }
      change(this._evaluationBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == NanhaiBookReadingTypes.favorite) {
      if (this
          ._myFavoriteBookItems
          .where((book) => book.bookId == bookId)
          .isNotEmpty) {
        this
            ._myFavoriteBookItems
            .where((book) => book.bookId == bookId)
            .first
            .readComplete = true;
        this
            ._myFavoriteBookItems
            .where((book) => book.bookId == bookId)
            .first
            .selected = false;
      }
      change(this._evaluationBookItems, status: RxStatus.success());
    }

    if (readingTypeFrom == NanhaiBookReadingTypes.search) {
      if (this
          ._searchedBookItems
          .where((book) => book.bookId == bookId)
          .isNotEmpty) {
        this
            ._searchedBookItems
            .where((book) => book.bookId == bookId)
            .first
            .readComplete = true;
        this
            ._searchedBookItems
            .where((book) => book.bookId == bookId)
            .first
            .selected = false;
      }
      change(this._searchedBookItems, status: RxStatus.success());
    }
  }

  // for book from icr
  // void readProgress(bookId, assignmentId, readProgress, readingType) async {
  //   try {
  //     updateBookStatus(bookId, readingType);
  //   } catch (error) {
  //     Log.debug(error);
  //   }
  // }

  Future<StatusMessageResult> readProgress(
      bookId, assignmentId, readProgress, readingType) async {
    var statusMessageResult = StatusMessageResult();
    try {
      EasyLoading.show();
      var response = await _bookServiceProvider.readProgress(
          bookId, assignmentId, readProgress);
      if (response.statusCode == 200) {
        var points = jsonDecode(response.bodyString)['points'];
        if (points > 0) {
          var _points = box.get('UserPoints');
          box.put("UserPoints", _points + points);
          bool isStudent = box.get(CacheManagerKey['nanhairole'].toString()) ==
              Constants.NanhaiRole_Student;
          bool isIndividual =
              box.get(CacheManagerKey['nanhairole'].toString()) ==
                  Constants.NanhaiRole_Individual;
          if (isStudent || isIndividual) {
            updateBookStatus(bookId, readingType);
          }
          statusMessageResult.status = 1000;
          statusMessageResult.message =
              jsonDecode(response.bodyString)['message'];
          // _statusMessageResult.value = _statusResult;
          // change(this._statusMessageResult, status: RxStatus.success());
        } else {
          statusMessageResult.status = 1000;
          statusMessageResult.message =
              jsonDecode(response.bodyString)['message'];
          //_statusMessageResult.value = _statusResult;
          //change(this._statusMessageResult, status: RxStatus.success());
        }
      }
    } catch (error) {
      Log.debug(error);
    } finally {
      EasyLoading.dismiss();
    }
    return statusMessageResult;
  }

  Future<String> getWriting(bookId, assignmentId) async {
    var res = '';
    try {
      var response =
          await _bookServiceProvider.getWriting(bookId, assignmentId);
      if (response.statusCode == 200) {
        _myWriting.value = jsonDecode(response.bodyString)['text'];
        change(this._myWriting, status: RxStatus.success());
        res = jsonDecode(response.bodyString)['text'];
      }
    } catch (error) {
      Log.debug(error);
    }
    return res;
  }

// save writing
  void saveWriting(bookId, assignmentId, writing) async {
    try {
      var response =
          await _bookServiceProvider.saveWriting(bookId, assignmentId, writing);
      if (response.statusCode == 200) {
        _statusResult.status = 1000;
        _statusResult.message = "This writing has been saved successfully!";
        _statusMessageResult.value = _statusResult;
        change(this._statusMessageResult, status: RxStatus.success());
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  // save and shared
  void shareWriting(bookId, assignmentId, writing) async {
    try {
      var response = await _bookServiceProvider.shareWriting(
          bookId, assignmentId, writing);
      if (response.statusCode == 200) {
        _statusResult.status = 1000;
        _statusResult.message = "This writing has been shared successfully!";
        _statusMessageResult.value = _statusResult;
        change(this._statusMessageResult, status: RxStatus.success());
      }
    } catch (error) {
      Log.debug(error);
    }
  }

  void fetchRecommendedBookItems(String bookId) async {
    try {
      //this._selectedLeveledReadingBookItems.clear();
      var response =
          await _bookServiceProvider.fetchgRecommendedBookItems(bookId);
      if (response.statusCode == 200) {
        var data = progressReadingBooksFromJson(response.bodyString);
        var _language = box.get('UserLanguage') ?? 'Simplified';
        List<BookItem> items = [];
        for (int i = 0; i < data.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data[i].book?.bookCode ?? '';
          item.audio = data[i].book?.audio ?? '';
          item.bookId = data[i].book?.bookId ?? '';
          item.bilingual = data[i].book?.bilingual ?? false;
          item.bookContentLink = data[i].book?.bookContentLink ?? '';
          item.simBookImageLink = data[i].book?.bookImageLink ?? '';
          if (_language == 'Traditional') {
            item.bookTitle = data[i].book?.traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
            // Log.debug(insertCharAt(item.simBookImageLink!,
            //     item.simBookImageLink!.length - 4, "t"));
          } else {
            item.bookTitle = data[i].book?.bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          item.description = data[i].book?.description ?? item.bookTitle;
          item.newArival = data[i].book?.newArival ?? false;
          item.topBook = data[i].book?.topBook ?? false;
          item.lastReadAt = data[i].lastReadAt ?? 0;
          item.quiz = data[i].book?.quiz ?? false;
          item.quizAvailable = data[i].quizAvailable ?? false;
          item.quizCount = data[i].quizCount ?? 0;
          item.quizLinkUrl = data[i].book?.quizLinkUrl ?? '';
          //api5
          item.color = data[i].book?.color ?? '#808080';
          item.bookLevel = data[i].book?.bookLevel ?? '';
          // item.color = data[i].book?.level?.color ?? '#808080';
          // item.bookLevel = data[i].book?.level?.levelCode ?? '';
          item.readComplete = data[i].readComplete ?? false;
          item.readCount = data[i].readCount ?? 0;
          item.readProgress = data[i].readProgress ?? 0;
          item.pass = data[i].pass ?? false;
          item.inFolder = data[i].inFolder ?? false;
          item.inAudioPlaylist = data[i].inAudioPlaylist ?? false;
          item.traditionalTitle = data[i].book?.traditionalTitle ?? '';
          item.viewMode = data[i].book?.viewMode;
          if (items.where((element) => element.bookId == item.bookId).length ==
              0) items.add(item);
        }

        // var userLevel = box.get('UserLevel').toString();
        // if (userLevel != '') {
        //   items = items.where((book) => book.bookLevel == userLevel).toList();
        _recommendedBookItems.assignAll(items);
        // }

        if (_recommendedBookItems.length > 0) {
          change(_recommendedBookItems, status: RxStatus.success());
        } else {
          change(null, status: RxStatus.empty());
        }
      } else {
        change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      }
    } catch (error) {
      change(null, status: RxStatus.error('Oops, something wrong ...'.tr));
      Log.debug(error);
    }
  }

  Future<dynamic> getRecommendedBookItems(String bookId) async {
    List<BookItem> items = [];
    try {
      var response =
          await _bookServiceProvider.fetchgRecommendedBookItems(bookId);
      if (response.statusCode == 200) {
        var data = progressReadingBooksFromJson(response.bodyString);
        var _language = box.get('UserLanguage') ?? 'Simplified';

        for (int i = 0; i < data.length; i++) {
          BookItem item = BookItem();
          item.bookCode = data[i].book?.bookCode ?? '';
          item.audio = data[i].book?.audio ?? '';
          item.bookId = data[i].book?.bookId ?? '';
          item.bilingual = data[i].book?.bilingual ?? false;
          item.bookContentLink = data[i].book?.bookContentLink ?? '';
          item.simBookImageLink = data[i].book?.bookImageLink ?? '';
          if (_language == 'Traditional') {
            item.bookTitle = data[i].book?.traditionalTitle ?? '';
            item.bookImageLink = StrUtil.insertCharAt(item.simBookImageLink!,
                    item.simBookImageLink!.length - 4, "t")
                .replaceAll('.gif', '.jpg');
            // Log.debug(insertCharAt(item.simBookImageLink!,
            //     item.simBookImageLink!.length - 4, "t"));
          } else {
            item.bookTitle = data[i].book?.bookTitle ?? '';
            item.bookImageLink = item.simBookImageLink;
          }
          item.description = data[i].book?.description ?? item.bookTitle;
          item.newArival = data[i].book?.newArival ?? false;
          item.topBook = data[i].book?.topBook ?? false;
          item.lastReadAt = data[i].lastReadAt ?? 0;
          item.quiz = data[i].book?.quiz ?? false;
          item.quizAvailable = data[i].quizAvailable ?? false;
          item.quizCount = data[i].quizCount ?? 0;
          item.quizLinkUrl = data[i].book?.quizLinkUrl ?? '';
          //api5
          item.color = data[i].book?.color ?? '#808080';
          item.bookLevel = data[i].book?.bookLevel ?? '';
          // item.color = data[i].book?.level?.color ?? '#808080';
          // item.bookLevel = data[i].book?.level?.levelCode ?? '';
          item.readComplete = data[i].readComplete ?? false;
          item.readCount = data[i].readCount ?? 0;
          item.readProgress = data[i].readProgress ?? 0;
          item.pass = data[i].pass ?? false;
          item.inFolder = data[i].inFolder ?? false;
          item.inAudioPlaylist = data[i].inAudioPlaylist ?? false;
          item.traditionalTitle = data[i].book?.traditionalTitle ?? '';
          item.viewMode = data[i].book?.viewMode;
          if (items.where((element) => element.bookId == item.bookId).length ==
              0) items.add(item);
        }
      }
    } catch (error) {
      Log.debug(error);
    }
    return items;
  }

  // reset Book Status after fail for quiz
  void resetBookStatus(String bookId, int percentage) async {
    String readingTypeFrom = box.get(CacheManagerKey['_readingType']);
    if (readingTypeFrom == 'library') {
      if (this
          ._openLibraryReadingBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        if (percentage < 75)
          this
              ._openLibraryReadingBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .readComplete = false;
        if (percentage >= 75)
          this
              ._openLibraryReadingBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .pass = true;
      }
      change(this._openLibraryReadingBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == 'leveled') {
      if (this
          ._leveledReadingBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        if (percentage < 75)
          this
              ._leveledReadingBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .readComplete = false;
        if (percentage >= 75)
          this
              ._leveledReadingBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .pass = true;
      }
      change(this._leveledReadingBookItems, status: RxStatus.success());
    }

    if (readingTypeFrom == 'assignment') {
      if (this
          ._assignedBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        if (percentage < 75)
          this
              ._assignedBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .readComplete = false;
        if (percentage >= 75)
          this
              ._assignedBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .pass = true;
      }
      change(this._assignedBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == 'evaluation') {
      if (this
          ._evaluationBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        if (percentage < 75)
          this
              ._evaluationBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .readComplete = false;
        if (percentage >= 75)
          this
              ._evaluationBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .pass = true;
      }
      change(this._evaluationBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == 'favorite') {
      if (this
          ._myFavoriteBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        if (percentage < 75)
          this
              ._myFavoriteBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .readComplete = false;
        if (percentage >= 75)
          this
              ._myFavoriteBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .pass = true;
      }
      change(this._evaluationBookItems, status: RxStatus.success());
    }

    if (readingTypeFrom == 'search') {
      if (this
          ._searchedBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        if (percentage < 75)
          this
              ._searchedBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .readComplete = false;
        if (percentage >= 75)
          this
              ._searchedBookItems
              .where((book) => book.bookId == bookId && book.pass != true)
              .first
              .pass = true;
      }
      change(this._searchedBookItems, status: RxStatus.success());
    }
  }

  // reset Book quick review Status after save
  void resetBookQuickReviewStatus(String bookId, String recordId) async {
    String readingTypeFrom = box.get(CacheManagerKey['_readingType']);
    if (readingTypeFrom == 'library') {
      if (this
          ._openLibraryReadingBookItems
          .where((book) => book.bookId == bookId)
          .isNotEmpty) {
        this
            ._openLibraryReadingBookItems
            .where((book) => book.bookId == bookId && book.pass != true)
            .first
            .quickReview = recordId;
      }
      change(this._openLibraryReadingBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == 'leveled') {
      if (this
          ._leveledReadingBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        this
            ._leveledReadingBookItems
            .where((book) => book.bookId == bookId && book.pass != true)
            .first
            .quickReview = recordId;
      }
      change(this._leveledReadingBookItems, status: RxStatus.success());
    }

    if (readingTypeFrom == 'assignment') {
      if (this
          ._assignedBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        this
            ._assignedBookItems
            .where((book) => book.bookId == bookId && book.pass != true)
            .first
            .quickReview = recordId;
      }
      change(this._assignedBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == 'evaluation') {
      if (this
          ._evaluationBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        this
            ._evaluationBookItems
            .where((book) => book.bookId == bookId && book.pass != true)
            .first
            .quickReview = recordId;
      }
      change(this._evaluationBookItems, status: RxStatus.success());
    }
    if (readingTypeFrom == 'favorite') {
      if (this
          ._myFavoriteBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        this
            ._myFavoriteBookItems
            .where((book) => book.bookId == bookId && book.pass != true)
            .first
            .quickReview = recordId;
      }
      change(this._evaluationBookItems, status: RxStatus.success());
    }

    if (readingTypeFrom == 'search') {
      if (this
          ._searchedBookItems
          .where((book) => book.bookId == bookId && book.pass != true)
          .isNotEmpty) {
        this
            ._searchedBookItems
            .where((book) => book.bookId == bookId && book.pass != true)
            .first
            .quickReview = recordId;
      }
      change(this._searchedBookItems, status: RxStatus.success());
    }
  }
}
